본문 바로가기

프로그래밍/Effective C#15

Effective C# Item 42 : IEnumerable<T> 데이터 소스와 IQueryable<T> 데이터 소스를 구분하라 IEnumerable 데이터 소스와 IQueryable 데이터 소스를 구분하라IQueryable와 IEnumerable는 거의 동일한 API 정의를 가진다. 따라서 이 두 인터페이스는 상호 교환 가능하다고 생각할 것이며 실제로도 대부분 그렇다. 이는 사실 의도한 설계이기도 하다. 하지만 시퀀스는 그냥 시퀀스일 뿐이어서 항상 이 둘을 서로 대체하여 사용할 수 있는 것은 아니다. 사실 이 둘은 동작 방식도 매우 다르고 성능 차이도 크게 난다. 다음의 예를 살펴보자. // 첫번째 예var q = from c in dbContext.Customers where c.City == "London" select c;var finalAnswer = from c in q orderby c.Name select c;// .. 2024. 9. 25.
Effective C# Item 36 : 쿼리 표현식과 메서드 호출 구문이 어떻게 대응되는지 이해하라 쿼리 표현식과 메서드 호출 구문이 어떻게 대응되는지 이해하라 LINQ는 쿼리 언어와 그 쿼리 언어를 일련의 메서드 집합으로 변환하는 2개의 핵심 구조를 기반으로 한다. C# 컴파일러는 쿼리 언어로 작성된 쿼리 표현식을 메서드 호출 구문으로 변환해 준다. 클래스 사용자의 관점에서 볼 때 쿼리 표현식은 단순히 메서드 호출 구문의 다른 표현 방법일 뿐이다. where 절은 적절한 인자를 이용하여 Where()라는 메서드를 호출하는 코드로 변환된다. 클래스 설계자의 관점에서는 기본 프레임워크에서 제공하는 메서드들이 어떻게 구현됐는지를 살펴보고 더 나은 방법으로 구현할 수 있을지를 판단해야 한다. 더 나은 구현 방법이 없다면 기본 라이브러리를 그대로 사용하면 되겠지만 개선의 가능성이 있다면 우선 쿼리 표현식이 메.. 2024. 2. 13.
Effective C# Item 17 : 표준 Dispose 패턴을 구현하라 표준 Dispose 패턴을 구현하라 비관리 리소스(Unmanaged Resource)를 포함하는 타입을 작성할 때 리소스 관리를 어떻게 해야 할지를 살펴보자. .NET Framework 내부에서는 비관리 리소스를 정의하는 표준화된 패턴을 사용하고 있으므로 새로운 타입을 만들 때도 동일한 패턴을 이용하는 것이 좋다. 바로 Dispose 패턴을 사용하면 된다. 이 패턴을 이용하면 개발자들에게 IDisposable 인터페이스를 통해서 리소스를 삭제할 수 있는 기능을 안정적으로 제공할 수 있다. 게다가 비관리 리소스를 명시적으로 정리해야 한다는 사실을 잊어버리거나 인지하지 못한 경우에도 finalizer를 통해 올바르게 리소스가 정리될 수 있도록 해준다. 표준 Dispose 패턴은 가비지 수집기와 연계되어 동작.. 2023. 11. 3.
Effective C# Item 13 : 정적 클래스 멤버를 올바르게 초기화하라 정적 클래스 멤버를 올바르게 초기화하라. 정적 멤버 변수를 포함하는 타입이 있다면 인스턴스를 생성하기 전에 반드시 정적 멤버 변수를 초기화해야 한다. 이를 위해 C#에서는 정적 멤버 초기화 구문(static member initializer) 정적 생성자(static constructors) 라는 두 가지 기능을 제공한다. 정적 생성자는 타입 내에 정의된 모든 메서드, 변수, 속성에 최초로 접근하기 전에 자동으로 호출되는 특이한 메서드다. 이 메서드를 활용하면 정적 변수를 초기화하거나, 싱글톤 패턴을 적용하거나, 혹은 여타의 작업을 효과적으로 수행할 수 있다. 정적 변수를 초기화하기 위해서 인스턴스 생성자나 전용의 private:메서드 혹은 다른 관용구를 사용해서는 안된다. 정적 필드를 초기화하는 과정이.. 2023. 10. 27.
Effective C# Item 8 : 이벤트 호출 시에는 null 조건 연산자를 사용하라. 이벤트 호출 시에는 null 조건 연산자를 사용하라 이벤트를 발생시키는 작업은 간단해 보인다. 이벤트를 정의하고, 이벤트를 발생시켜야 할 경우 이벤트를 호출하기만 하면 이벤트에 결합되어 있는 이벤트 핸들러가 호출될 것이기 때문이다. 멀티캐스트 델리게이트의 경우 이벤트에 결합된 이벤트 핸들러가 여러 개지만 내부적으로 이를 순차적으로 호출해 줄 것이므로 복잡성이 외부로 드러나지 않는다. 하지만 실제로는 이벤트를 호출하는 경우 다양한 문제가 발생하곤 한다. 우선 이벤트에 결합된 이벤트 핸들러가 없다면 어떻게 될까? 이벤트 핸들러가 결합되어 있는지를 확인하는 코드를 추가하면 된다고 생각할지 모르지만, 이벤트 핸들러가 결합되어 있는지 확인하는 코드와 이벤트를 발생시키는 코드 사이에 경쟁 조건(race condit.. 2023. 10. 26.
Effective C# Item 16 : 생성자 내에서는 절대로 가상 함수를 호출하지 말라 생성자 내에서는 절대로 가상 함수를 호출하지 말라 객체가 완전히 생성되기 이전에 가상 함수를 호출하면 이상 동작을 일으킨다. 어떤 타입이든 생성자가 수행을 완료할 때까지는 객체가 완전히 생성되었다고 할 수 없다. 따라서 생성자 내에서 가상 함수를 호출하면 예상처럼 동작하지 않는다. 다음 코드를 살펴보자. class B { protected B() { VFunc(); } protected virtual void VFunc() { Console.WirteLine("VFunc in B"); } } class Derived : B { private readonly string msg = "Set by initializer"; public Derived(string msg) { this.msg = msg; } p.. 2023. 10. 25.