Lang/C#
[More Effective C#] Chapter 4. 요약 (2)
[ Item 40 : 동기화에는 lock()을 최우선으로 사용하라 ]스레드들은 서로 통신할 수 있어야 한다.즉, 같은 애플리케이션에 속한 스레드들은 데이터를 안전하게 주고받을 수 있는 수단이 있어야 한다. 데이터 무결성 오류로 인한 잠재적 문제를 피하려면 모든 공유 데이터의 상태가 일관되게 유지되고 있음을 확신할 수 있어야 하고, 그렇게 하려면 동기화 요소(synchronization primitive)를 사용해서 공유 데이터에 대한 접근을 제어해야 한다. 동기화 요소는 특정 스레드가 임계 영역 내에서 연산을 수행하는 동안 다른 스레드로부터 이를 보호하는 역할을 수행한다.그래서 C# 에서는 동기화 작업을 수월하게 할 수 있도록 lock() 블록을 사용해서 임계 영역을 지정하고, 동기화를 올바르게 제어할 ..
[More Effective C#] Chapter 4. 요약 (1)
[ Item 35 : PLINQ가 병렬 알고리즘을 구현하는 방법을 이해하라 ] PLINQ 를 사용하면 멀티코어 프로그래밍에 쉽게 접근할 수 있다. 데이터 접근을 위해 언제 동기화돼야 하는지 알아야 한다. ParallelEnumerable에 선언된 병렬 버전과 순차 버전 메서드의 효과를 측정해야 한다. 개별 요소들을 반드시 순차적으로 접근해야만 하는 메서드가 있다는 것을 알아야 한다. PLINQ를 사용하는 예시 150 보다 작은 모든 수에 대해 n! 을 계산하는 쿼리 var nums = data.Where(d => d Factorial(n)); 파이프라인의 첫 번째 메서드에 AsParallel()을 추가하면 병렬 연산이 가능해진다. var nums = data.AsPara..
[More Effective C#] Chapter 3. 요약 (2)
[ Item 31 : 불필요한 콘텍스트 마샬링을 피하라 ] 현재 아이템은 SynchronizationContext와 관련된 성능 문제를 다룬다. 특히, 멀티스레딩 환경에서 특정 Context로의 데이터 전달이나 메서드 호출이 필요할 때 발생하는 마샬링 오버헤드를 최소화하는 방법을 집중해서 다룬다. ‘자유 코드’ 어떤 context에서도 실행될 수 있는 코드 우리가 작성하는 대부분의 코드는 자유 코드이다. ‘Context 인식 코드’ 특정 SynchronizationContext 에서만 실행될 수 있는 코드 GUI 애플리케이션에서 UI 컨트롤과 상호작용하는 코드 웹 애플리케이션에서 HTTPContext 등의 클래스와 상호작용하는 코드 콘텍스트 마샬링이란? 하나의 스레드에서 다른 스레드로 데이터를 전달하거나..
[More Effective C#] Chapter 3. 요약 (1)
[ Item 27 : 비동기 작업에는 비동기 메서드를 사용하라 ] 동기 메서드에서는 코드들이 작성한 순서대로 실행된다. 하지만 비동기 메서드에서는 꼭 그렇지 않을 수 있다. 비동기 메서드는 내부 코드를 모두 수행하기 전에 미리 반환될 수 있으며, 내부적으로 요청한 비동기 작업이 완료되는 시점에 맞추어 수행을 중단했던 지점부터 다시 수행을 이어간다. private async Task SomeMethodAsync() { Console.WriteLine($"Entering {nameof(SomeMethodAsync)}"); var awaitable = SomeMethodReturningTask(); Console.WriteLine($"In {nameof(SomeMethodAsync)}, before the a..
[More Effective C#] Chapter 2. 요약 (2)
[ Item 19 : 베이스 클래스에 정의된 메서드를 오버로드해서는 안된다 ] 베이스 클래스에서 정의된 메서드를 파생 클래스에서 오버로드하면 어떤 메서드가 호출될지 정확히 이해하기가 어려워진다. 1. 명확한 메서드 이름을 사용한다 해당 기능을 명확하게 설명하는 이름을 지어주자. 2. 오버라이딩을 통해 기능을 확장한다 기존 메서드의 기능을 수정하거나 확장해야 할 때는, 오버라이딩을 사용하자. 3. 메서드 오버로딩 최소화 베이스 클래스의 메서드와 동일한 이름을 가진 새로운 메서드를 추가할 필요가 있을 때는, 혼란을 피하기 위해 가능한 한 메서드 오버로딩을 피하고 다른 이름을 지어주자. [ Item 20 : 이벤트가 런타임 시 객체 간의 결합도를 증가시킨다는 것을 이해하라 ] 이벤트 기반 API에는 결합도를 ..
[More Effective C#] Chapter 2. 요약 (1)
[ Item 11 : API에는 변환 연산자를 작성하지 말라 ] 1. 다른 타입을 원하는 커스텀 타입으로 변환하고 싶을 때는 생성자를 사용하라. 생성자는 새로운 객체를 만든다는 사실을 명확히 알려준다. public class Circle { ... static public implicit operator Ellipse(Circle c) { return new Ellipse(...) } } public static void Flatten(Ellipse e) { e.r1 /= 2; } var c = new Circle(...); Flatten(c); // Circle -> Ellipse 로 암묵적 변환 따라서 위와 같은 상황에서 Flatten() 함수는 암묵적 변환 과정에서 새롭게 생성된 Ellipse 객체..
[More Effective C#] Chapter 1. 요약
[ Item 1 : 접근 가능한 데이터 멤버 대신 속성을 사용하라 ] public 필드 대신 프로퍼티를 사용하도록 권장한다. 실제로 .NET 프레임워크의 데이터 바인딩 클래스들은 public 필드 대신 프로퍼티에 대해서만 동작한다. 예를 들어 WPF의 INotifyPropertyChanged, 윈폼 등에 포함된 모든 데이터 바인딩 라이브러리가 그렇다. Java에서는 getter, setter 메서드를 만드는 것 처럼(lombok을 쓰지만..) C# 에서는 { get; set; } 키워드로 간편히 설정할 수 있다는 게 비슷한 점이라고 생각된다. OOP 에서의 캡슐화에 큰 도움이 된다. 프로퍼티는 메서드로 구현되기에 멀티스레딩 환경도 쉽게 지원할 수 있고, Virtual 으로도 설정해줄 수 있다. 멀티스레딩..
[Effective C#] C# 언어 요소
Item 1 : 지역변수를 선언할 때는 var를 사용하는 것이 낫다 코드를 읽을 때 타입을 명시적으로 드러내야 하는 경우가 아니라면 var를 사용하는 것이 좋다. var를 사용하면 변수의 타입과 같이 지엽적인 부분보다 변수의 의미 파악에 더 집중할 수 있다. 그리고 타입을 명시적으로 지정할 경우 타입 안정성이 향상될 것이라 생각하지만 이 또한 사실이 아니다. 개발자가 올바르게 타입을 지정하지 않으면 오히려 타입 안정성이 떨어지기 때문이다. var는 지역 변수에 대한 타입 추론을 사용한다. 이는 동적 타이핑과는 다른 것이다. (C#은 정적 타이핑 언어이다.) 동적 타이핑을 사용하는 언어로는 Python, Javascript 등이 있다. 명시적으로 지정하는게 더 좋은 경우 내장 숫자 타입을 사용하는 경우 숫..