목록C# (122)
방프리
Item 23 : 생성자, 변경자, 이벤트 핸들러를 위해 partial 클래스와 메서드를 제공하라 C#에서는 UI와 코드를 분리하기 위해서 partial이라는 키워드를 생성했다. 이로인해 디자이너와 개발자의 영역을 확실히 구분되었다. (각 부분에서 문제가 생기면 자기가 맡은 영역만 확인) C# 3.0 버전에서는 기본 partial에서 새로운 기능을 추가하였는데 바로 partial 메서드이다. 간단히 설명하자면 기본 partial 클래스의 역할에서 조금 더 세분화되어 구현영역과 선언영역을 분리했다고 보면 좋을 것 같다. (처음 예제를 보고 C++의 .h 와 .cpp 의 구조를 보는 듯 했다.) 대신 struct, class, interface와 달리 partial method를 선언할 때에는 약간의 제약이..
1. async 메서드의 단위 테스트 //단위 테스트 프레임워크가 async Task를 지원한다면 [TestMethod] public async Task MyMethodAsync_ReturnsFalse() { var objectUnderTest = ...; bool result = await objectUnderTest.MyMethodAsync(); Assert.IsFalse(result); } //async Task를 지원하지 않는다면, Nito.AsyncEx Nuget 패키지 사용해볼 것 [TestMethod] public void MyMethodAsync_ReturnsFalse() { AsyncContext.Run(async () => { var objectUnderTest = ...; bool r..
Item 22 : 명확하고 간결하며 완결된 메서드 그룹을 생성하라 API를 구성할 때 유의해야할 점이 사용하는 사람이 보았을 때 혼동이 있어서는 안된다. 명확하고 사용자가 API를 사용함으로써 실수를 줄일 수 있는 몇 가지 방법이 있다. 1. 적은 양의 오버로드 함수 - 오버로드된 함수를 만드는 것은 좋으나, 그 개수가 많아진다면 사용자 측면에서 혼동이 일어날 수 있다. 나중에는 각 함수 별 각주를 달거나 사용자가 해당 API를 사용할 때마다 기능을 확인해야 하는 경우가 발생할 수 있으니 무분별한 오버로드 함수는 좋지 않다. 2. 동일 명에 동일 동작이 원칙 - 같은 메서드 명이라면 그 안에서 동작하는 행위는 무조건 같아야 한다. 다를 경우 사용자 측면에서 구분하기 어렵고 사용 시 예측 불가능한 동작이 ..
1. 닷넷 이벤트 변환 - FromEventPattern을 통해 범용적인 이벤트를 사용 - EventPattern을 선언할 때 강력하게 할 것인가? 혹은 강력한 데이터를 포기할 것인가 //강력한 데이터를 가져올 때 var timer = new System.Timers.Timer(interval: 1000) { Enabled = true }; IObservable ticks = Observable.FromEventPattern( handler => (s, a) => handler(s, a), handler => timer.Elapsed += handler, handler => timer.Elapsed -= handler); ticks.Subscribe(data => Console.WriteLine("OnN..
1. 블록 연결 var multiplyBlock = new TransformBlock(item => item * 2); var subtractBlock = new TransformBlock(item => item - 2); //PropagateCompletion 옵션을 통해 연결 대상의 완료 및 오류 알림 여부 확인 var options = new DataflowLinkOptions { PropagateCompletion = true }; multiplyBlock.LinkTo(subtractBlock, options); ... //첫 번째 블록의 완료를 자동으로 두 번째 블록에 전파한다. multiplyBlock.Complete(); await subtractBlock.Completion; 2. 오류 전..
1. 데이터의 병렬처리 - 병렬로 여러 데이터를 반복문을 통해 처리할 때 - 만약 공유하는 변수 혹은 리소스가 있다면 잠금(lock)을 사용해보는 것도 좋다. - 책에서는 ForEach 위주로 설명하였지만 순차처리를 목적으로 한다면 ForEachAsync도 고려해볼만 하다. void RotateMatrices(IEnumerable matrices, float degrees, CancellationToken token) { Parallel.ForEach(matrices, new ParallelOptions { CancellationToken = token }, matrix => matrix.Rotate(degress)); } 2. 병렬 집계 - 병렬 작업이 끝난 후 결과를 집계할 때 int Parallel..
1. 비동기 스트림 생성 - yield return을 사용해서 반환 - 비동기 스트림은 내부적으로 ValueTask를 사용, 취소해야할 경우 CancellationToken을 사용하여 취소 async IAsyncEnumerable GetValuesAsync(HttpClient client) { var offset = 0; const int limit = 10; while (true) { var result = await client.GetStringAsync( $"https://example.com/api/values?offset={offset}&limit={limit}"); string[] valuesOnThisPage = result.Split('\n'); foreach (string value in..
1. 일정 시간동안 정지 - 간단한 딜레이 타임을 주는 정도의 기능 - 시나리오 코드 및 간단한 테스트 용도로 사용한다. (이외 실제 기능 혹은 배포에서는 들어가면 좋지 않은 코드) async Task DelayResult(T result, TimeSpan delay) { await Task.Delay(delay); return result; } // delay를 통한 soft timeout 기능 구현 async Task DownloadStringWithTimeout(HttpClient client, string url) { using var tokenSource= new CancellationTokenSource(TimeSpan.FromSecond(3)); Task downloadTask = clien..