[Effective C# Item 8] 이벤트 호출 시에는 null 조건 연산자(?.)를 사용하라 이벤트를 발생 시키는 작업은 언뜻보면 그저 단순한 작업에 불과하다고 생각할지 모른다. 하지만, 이벤트에 결합된 이벤트 핸들러가 없다면 NullReferenceException이 발생한다. 이를 해결하기 위해서 이벤트 핸들러가 결합되어 있는지 확인하는 코드를 추가해주면 된다. 하지만 또 문제가 발생할 수 있다. 이벤트 핸들러의 유무 확인 후에 다른 스레드에서 이벤트 핸들러 처리에 관한 작업이 실행될지도 모르기 때문이다. 다음 예제를 통해서 더 자세히 알아보자. 간단한 이벤트 발생 코드 public class EventSource { private EventHandler Updated; public ..
7) 델리게이트를 이용하여 콜백을 표현하라 콜백을 설명하기 위한 간단한 대화로 시작해보자. 공장장 : "기모씨, 제가 공장 둘러보는 동안 A 공정 파트 좀 민수씨가 맡아 주고 전화로 상태 보고해주세요~" 안기모 : "공장장님, 우선 A-1 공정 끝냈습니다." 안기모 : "공장장님, A-2 공정 끝냈습니다." 안기모 : "공장장님, A-3 공정 을 위한 기계가 고장났습니다." 공장장 : "아 그래요? 제가 설비 관리 팀에 문의 넣어 놓을게요." 잠시후 안기모 : "공장장님, A 공정 완료했습니다." 공장장은 안기모씨에게 A 공정이라는 일을 시켰고 안기모씨는 여러 차례에 걸쳐 공장장에게 일 상태를 보고했다. 공장장은 공장 여러 곳을 둘러보다가도 잠깐씩 A공정의 상태를 같이 체..
6) nameof() 연산자를 적극 활용하라 분산 시스템이 널리 활용되면서 서로 다른 플랫폼, 언어로 개발된 프로그램들 사이에서도 데이터를 주고 받을 일이 많아졌다. 이런 차이를 극복하기 위해서 이름이나 string 식별자에 의존하는 라이브러리들이 많이 사용된다고 한다. 하지만 이런 방식은 간편할지라도 여러가지 단점이 생기곤 하는데, 가장 대표적인 단점이 타입 정보를 손실한다는 것이다. 이로 인해서, 타입 정보를 활용해서 추가 기능을 제공하는 개발 도구를 쓰는데 어려움을 겪고, 정적 타입 언어이 주요 장점을 상실한다. 그래서 C# 설계팀은 C# 6.0에 nameof()라는 연산자를 추가했다. 이 키워드는 심볼 그 자체를 해당 심볼을 포함하는 string으로 대체해준다. name of 연산자를 ..
5) 문화권별로 다른 문자열을 생성하려면 FormattableString을 사용하라 앞선 보간 문자열을 다루는 글에서 문자열 보간 기능을 이용해서 가독성 좋은 string 생성 방법을 배웠다. 하지만 여러 문화권과 다양한 언어를 다뤄야 하는 경우에는 좀더 세부적인 제어가 필요하기 때문에 문자열을 생성하는 과정을 조금 더 자세히 알아둬야 한다. 앞의 글에서 다뤘듯이, 문자열 보간 기능을 이용해서 string을 생성할 경우 아래 코드와 같이 선두에 '$'를 붙이고 중괄호 { }를 사용해서 string을 생성하는 것이 전부다. 근데 특이한 것은 이 보간 기능의 결과로 생성되는 반환값의 타입이 string일 수도 있지만 FormattableString을 상속하는 타입일 수도 있다. string fir..
4) string.Format()을 보간 문자열로 대체하라 C#에서도 C에서 널리 사용되는 string.Format과 같은 방법으로 string을 만들 수 있지만 C# 6.0에 새롭게 도입된 문자열 보간 기능을 사용하는 편이 여러모로 좋다. 문자열 보간 기능의 장점 1. 코드 가독성이 매우 좋아진다. 2. 컴파일러 입장에서는 정적 타입 검사를 수행할 수 있기 때문에 개발자의 실수를 미리 방지할 수 있다. 3. 기존 방식에 비해 string을 생성하기 위한 표현식이 다양하다. 기존에 사용되는 string.Format() 형식은 포맷 문자열과 출력할 내용을 담고 있는 배열이 나뉘어 전달되면서 string이 생성된다. 포맷 문자열에 나타난 인수의 개수와 실제 전달된 인수의 개수가 일치하지 않는 ..
3) 캐스트보다는 is, as가 더 좋다 C#은 정적 타이핑을 수행하는 언어다. 따라서 타입이 일치하지 않더라도 컴파일러가 컴파일타임 에러를 잡아주기 때문에 타입 검사를 자주해줄 필요는 없다. 하지만 코딩을 하다보면 형변환을 수행해야할 경우가 생긴다. (정적 타이핑에 대한 간단한 소개는 다음 링크를 참조해주었으면 한다 - https://devmas.tistory.com/entry/%EB%8F%99%EC%A0%81%ED%83%80%EC%9D%B4%ED%95%91 - https://itmining.tistory.com/65) 형변환을 하는 방법은 캐스트 연산자 구문을 사용하는 방법, as 연산자를 사용하는 방법이 있으며 더 방어적으로 형변환을 하고 싶다면 is 연산자를 사용하여 형변환이 가능한지를..
2) const보다는 readonly가 좋다 C#에는 컴파일타임 상수와 런타임 상수가 있다. 결론부터 말하자면 컴파일타임 상수보다는 런타임 상수를 사용하는 편이 좋다. 컴파일타임 상수가 약간 더 빠르긴 해도 성능면에서 차이가 크지 않고 런타임 상수를 사용하여 얻을 수 있는 유연성이라는 장점은 큰 이득이다. 그래서 컴파일타임 상수는 성능이 중요하고 상수의 값이 절대로 어떤 경우에도 바뀌지 않을 때 사용해야 한다. 런타임 상수는 readonly 키워드를 사용하고, 컴파일타임 상수는 const를 사용한다. // 컴파일타임 상수 public const string MyName = Kim Min Soo; // 런타임 상수 public static readonly MyNickname = SoBoroo; re..
1) 지역변수를 선언할 때는 var를 사용하는 것이 낫다 C#은 타입을 암시적으로 선언할 수 있는 var을 제공한다. 특정 변수를 var로 선언하면 연산자 오른쪽의 타입을 환산하여서 왼쪽 변수의 타입을 결정하게 된다. 그렇다면 var를 무작정 사용하면 타입 선정하는 데 걸리는 시간이 늘어나 컴파일 타임에 악영향을 주는게 아닐까? 결론부터 말하자면 "그렇지 않다." 이다. var를 사용한다고 해서 컴파일 타임에 큰 영향을 주지도 않을 뿐더러 몇 가지 이득을 취할 수 있다. 1. 암시적으로 변수를 선언한 코드가 더 잘 읽힌다. var를 사용하면 변수의 타입 같은 중요하지 않은 부분보다 변수의 의미 자체에 더 집중할 수 있다. 하지만 변수의 타입 정보가 필요할 때, 정확하게 유추할 수..