목록C#/More Effective C# (48)
방프리
Item 48 : 가장 인기 있는 답이 아닌 최고의 답을 찾으라커뮤니티가 커짐으로써 문제를 해결해 나아가는 답이 이전 버전들에서 사용되던 답일 수 있다. 인기 있는 답이 새로운 기술을 적용한 가장 최신의 기술이 아닐 수 있기에 필자는 다음의 할일을 명시하였다.1. 답을 검색할 대 가장 인기 있는 답이 아닌 최신 C# 언어의 기능을 활용한 최고의 답을 찾는다.2. 최고의 답을 찾았다면 그 답을 지지해야 한다3. 웹페이지 수정할 수 있는 경우라면 가장 있기 있는 답을 수정해서 최신의 답을 살펴볼 수 있도록 만들자4. 자신의 코드를 수정할 때마다 더 나은 코드로 만드려고 노력하자Item 49 : 명세와 코드 향상에 기여하라깃허브에 공개된 .NET 언어 플랫폼인 로슬린과 C# 언어 설계를 뜻하는 CSharpL..
Item 47 : Public API에서는 동적 객체 사용을 최소화하라dynamic 객체는 건드리는 모든 것을 동적으로 만들어버리기에 사용 시 매우 주의해야 한다. 작업의 대상이 되는 매개 변수 중 하나라도 dynamic이라면 그 결과도 dynamic이 된다. 또한 메서드가 동적 객체를 반환하면 그 객체를 사용하는 모든 것이 동적 객체가 된다.C#은 기본적으로 정적 타입을 선호하며 일부 영역에 동적 타이핑을 적용한다는 점을 반드시 알고 있어야 한다. 만약 주 타이핑 방식이 동적으로만 이루어진다면 언어 선택에 대한 의구심을 가질 필요가 있다. 동적 프로그래밍은 취지는 좋으나 특성상 런타임에 리소스를 많이 사용해야 한다는 점을 알고 있어야 한다. 또한 public 인터페이스에서는 가능한 제외되어야 한다. 동..
Item 43 : 동적 타이핑의 장단점을 이해하라dynamic 타입은 '런타임에 바인딩되는 System.Object'.라고 볼 수 있다. 따라서 컴파일타임에 dynamic 타입의 변수는 System.Object에 정의된 메서드만 가지고 있다. 런타임 시 객체의 타입을 확인하고, 수행할 메서드가 지원되는지 확인한다. 이 방식을 덕 타이핑이라고 부른다. 이 방식은 특별히 인터페이스를 선언하거나, 커파일타임 타입 연산을 제공할 필요가 없다. 동적 타이핑은 타입에 대한 대처를 유연하게 할 수 있지만 타입 안정성을 고려하지 않으며 컴파일러가 도와줄 수 있는 범위가 한정적이기에 오류를 런타임에 찾을 수 있다는 단점이 있다.표현식 트리는 런타임에 코드를 구성하는 방법 중 하나인데 System.Linq.Expressi..
Item 46 : 표현식 API의 사용법을 익혀두라C#에 LINQ와 동적 지원 기능이 추가되면서 표현식과 표현식 트리를 사용해 동적 프로그래밍이 가능하다.표현식은 코드처럼 보이며 많은 경우 델리게이트로 컴파일하여 사용한다.표현식을 사용하게되면 여러 제약조건으로 메서드를 사용할 때 코드량을 줄이면서 유연하게 사용이 가능하다.public TResult CallInterface(Expression> op){ var exp = op.Body as MethodCallExpression; var methodName = exp.Method.Name; var methodInfo = exp.Method; var allParameters = from element in exp.Arguments ..
Item 45 : 데이터 주도 동적 타입에는 DynamicObject나 IDynamicMetaObjectProvider를 사용하라동적 프로그래밍의 큰 장점 하나는 런타임에 public 인터페이스가 바뀌는 타입을 만들 수 있다는 것이다. C#에서는 dynamic과 System.Dynamic.DynamicObject 베이스 클래스 그리고 System.Dynamic.IDynamicMetaObjectProvider 인터페이스를 통해 동적 능력을 갖춘 고유의 타입을 만들 수 있다.동적 능력을 가지는 타입을 만드는 다음과 같다.1. System.Dynamic.DynamicObject 상속- 가장 구현이 쉬운 방법 이 타입은 IDynamicMetaObjectProvider 인터페이스를 구현한 중첩 private 클래..
Item 44 : 동적 타이핑의 장단점을 이해하라Cast는 제네릭 메서드로, T타입으로 타입 변환이 가능하기만 하다면 어떤 타입이든 사용할 수 있다. 하지만 Cast의 한계에 대해서 제대로 알지 못하면 예상대로 동작하지 않기에 제대로 알고 사용해야한다.// 동작되지 않는 코드var answer1 = GetSomeStrings().Cast();try{ foreach (var v in answer1) WriteLine(v);}catch (INvalidCastException){ WriteLine("Cast Failed!");}Cast는 인수 런타임 타입에서 제공하는 사용자 정의 변환 함수에는 접근할 수 없다. 단순히 참조 변환가 박싱 변환만 가능하기에 Cast는 T가 System.Ob..
Item 42 : 잠김 영역에서는 외부 코드 호출을 삼가라lock을 통해 보호하는 영역 내에서 리스너를 통해 함수를 호출하는 방식은 교착상태를 불러 일으킬 수 있다.public class WorkerClass{ public event EventHandler RaiseProgress; private object syncHandle = new object(); public void DoWork() { for (int count = 0; count 위와 같이 코드를 작성하였을 때 Progress 객체에 접근할 때와 engine_RaiseProgress 함수를 호출할 때 교착상태가 발생할 확률이 매우 크다. 이 문제는 아래와 같이 수정하여 회피하는 것이 좋다...
Item 41 : 락은 가능한 한 좁은 법위에 적용하라 private 접근제한자를 통해 멤버 변수를 관리할 범위를 최소화하는 것처럼 lock 또한 최소 단위로 관리해야 한다. 필자는 lock을 관리하는 총 3가지 방식을 제안한다 1. MethodImplAttribute를 사용해서 메서드 전체를 보호한다. 가장 드물게 사용 [MethodImpl(MethodImplOptions.Synchronized)] public void IncrementTotal() { total++; } 2. 개발자에게 현재 타입이나 현재 객체에만 락을 걸도록 의무화한다. 즉, 모두가 lock(this)나 lock(MyType)을 사용하도록 권장한다. 하지만 위의 방식은 전 세계 개발자 모두가 가이드를 지켜야 하므로 수행되기 어려움 ..