본문 바로가기

Develop/.NET 가이드

[C#] 예외처리 Best Practices 예외처리 Best Practices 1. 리소스를 사용하다가 오류가 발생했을 때 finally 를 활용하자. IDisposable 인터페이스를 구현한 리소스를 사용하다가 오류가 발생했을 때 오류만 잡고 리소스를 해제하는 걸 깜빡하는 경우가 자주 있습니다. 리소스를 사용하다가 오류가 발생할 만한 부분에 finally 문을 정의하고 리소스를 Dispose() 하여 메모리가 누수되지 않도록 합시다. try { var resource = new Resource(); } finally { resource.Dispose(); } 2. 예외를 발생시킬 때와 방지해야 할 때는 발생 빈도로 결정하자. 예외를 반드시 try/catch 문으로 해결할 필요는 없습니다. 예외의 발생 빈도가 높다면 예외가 발생하지 않도록 미연에..
[C#] 리플렉션 Reflection (4) : 복잡한 if 문 대신 리플렉션으로 생성 함수 호출하기 복잡한 if 문 대신 리플렉션으로 객체 생성하기 프로젝트를 진행하면서 아래 예제 코드와 같이 형타입에 따라 다른 객체를 생성해야 하는 경우가 있었습니다. if( data is DataTypeA a) { var model = new DataModelA(a); list.Add(model); } else if( data is DataTypeB b) { var model = new DataModelB(b); list.Add(model); } // 엄청 긴 if 문~ 위 예제 코드와 같은 구조로 개발을 하게 되면 데이터 타입이 추가될 때마다, if 문은 계속 길어질 수 밖에 없고 데이터 타입에 따라 DataModel을 생성하는 논리가 달라지면서 if 문 내부도 복잡해져갔습니다. 이러한 구조로 인해 점점 코드는 더..
[C#] 리플렉션 Reflection (3) : PropertyDescriptor.SetValue에 TypeConverter 로 데이터 형변환하기 PropertyDescriptor.SetValue에 TypeConverter 활용하기 리플렉션 Reflection (2) : 타입에 따라 동적으로 객체 생성하기 글에서 TagFactory를 통해 Tag 클래스에 속성 값을 입력할 때, XML 파일의 string을 읽어 string으로 객체에 저장하기 때문에 형변환 문제가 발생하지는 않았습니다. 기본 데이터 타입으로 변환할 때는 문제가 발생하지 않았지만, 만약 개발자가 정의한 클래스로 저장해야 한다면 문제가 발생하게 됩니다. 이러한 데이터 변환 문제를 해결하는 방법을 알려드리도록 하겠습니다. propertyDescriptor.SetValue(tag, propertyDescriptor.Converter.ConvertFromInvariantString(attr..
[C#] 리플렉션 Reflection (2) : 타입에 따라 동적으로 객체 생성하기 타입에 따라 동적으로 객체 생성하기 바로 사용할 수 있는 예제로 리플렉션(Reflection) 기술을 설명드리도록 하겠습니다. 먼저 예제를 사용하는 상황을 설명드리자면, XML 파일을 Parse 해서 태그별로 객체를 생성하려는 상황입니다. 제가 맨 처음 도입한 방식은 누구나 쉽게 떠올릴 수 있는 방법인 태그 이름에 따라 switch 문을 사용한 방법입니다. var tags = new List(); while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.Element) { switch (xmlReader.Name) { case "A": // A 태그를 해석하여 객체를 만들고 저장합니다. var a = new TagA(xmlReader.GetAtt..
[C#] 리플렉션 Reflection (1) : 왜 알아야 할까? 리플렉션 Reflection 리플렉션 (Reflection) 은 프로그램이 동적으로 소스 코드를 해석할 수 있게 하는 기술입니다. Activity나 Service 같이 특정 이름 규칙으로 클래스를 작성하면 개발자가 코드로 객체를 생성하거나 연결하지 않아도, 프로그램 내에 등록되고 사용할 수 있었던 마법의 원리는 프레임워크가 리플렉션 기술을 사용해 클래스의 이름을 바탕으로 클래스를 생성/관리/제거해주기 때문입니다. 객체를 프레임워크가 관리해주니까, 개발자는 프레임워크에게 요청하면 언제 어디서나 안정적으로 원하는 클래스를 얻을 수 있습니다. 즉 개발자는 클래스로 객체를 생성하는 거나, 객체를 사용할 수 있게 준비하는 일정 부분을 프레임워크에게 믿고 맡길 수 있게 됩니다. 예제 코드를 보여드리자면, 아래와 같..
[C#] 병렬 프로그래밍 Parallel Programming (4) - 데이터 흐름 예제 데이터 흐름 예제 기초 예제 아래 예제는 비동기로 BufferBlock 데이터 흐름 블록에 데이터를 입력했다가 출력하는 예제입니다. var bufferBlock = new BufferBlock(); // bufferBlock 에 비동기로 데이터 넣기 for (int i = 0; i < 3; i++) { await bufferBlock.SendAsync(i); } // bufferBlock 에 비동기로 데이터 빼기 for (int i = 0; i < 3; i++) { Console.WriteLine(await bufferBlock.ReceiveAsync()); } /* 결과: 0 1 2 */ 아래 예제는 병렬로 데이터 흐름 블록에 데이터를 입력했다가 출력하는 예제입니다. var bufferBlock = n..
[C#] 병렬 프로그래밍 Parallel Programming (3) - 데이터 흐름 데이터 흐름 데이터 흐름은 프로그래밍 패러다임이 다른 병렬 프로그래밍입니다. 일반적으로 배우는 프로그래밍 언어는 코드로 절차를 정의하고 실행해 결과를 만듭니다. 절차는 메서드로 구현되고 메서드의 실행 순서에 따라 프로그램이 동작합니다. 반면, 데이터 흐름은 절차가 아닌 데이터가 중심입니다. 데이터 중심이란 데이터로 프로그램의 동작을 정의하게 되는걸 의미합니다. 데이터 흐름에서 프로그램은 필요한 데이터를 준비시키고, 데이터가 준비되어야 다음 연산을 실행합니다. 다시말해 프로그램은 데이터가 준비되어야만 진행됩니다. 예를 들어 여러 이미지를 합성해 하나의 이미지로 만드는 프로그램은 소스가 되는 이미지들이 준비되었는지를 먼저 확인합니다. 소스 이미지들이 준비되었으면 프로그램은 이미지를 합성하는 연산을 진행합니다..
[C#] 병렬 프로그래밍 Parallel Programming (2) - 작업 병렬화 작업 병렬화 Task Parallelism 작업 병렬화는 일반적으로 생각하는 병렬 처리를 방식입니다. 작업 병렬화는 데이터 병렬화와 달리, 데이터마다 동일한 처리를 하는 방법이 아닌, 독립적인 작업들을 동시에 처리하는 방식입니다. 데이터 병렬화와 마찬가지로 작업 병렬화도 TPL 이 개발자를 대신하여 스레드를 관리합니다. 따라서 개발자는 병렬 프로그래밍을 Parallel.Invoke 메서드를 사용해 아래와 같이 손쉽게 구현할 수 있게 되었습니다. Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork()); 예제 코드는 Parallel.Invoke 메서드로 DoSomeWork() 과 DoSomeOtherWork()을 병렬로 처리하고 있습니다. 코드의 내부 동..