C++이나 Java처럼 C#을 사용하면 C#의 고유한 장점을 살릴 수 없을 뿐더러 심각한 문제 상황에 처할 수 있다. 이번 챕터에서는 C#을 C#답게 쓰기 위한 핵심 요소를 살펴볼 것이다.
아이템 1: 지역변수를 선언할 때는 var를 사용하는 것이 낫다
- C#언어는 익명타입을 지원하기 위해 타입을 암시적으로 선언할 수 있는 손쉬운 방법을 제공한다.
- 정확한 반환 타입을 알지 못한 채 올바르지 않은 타입을 명시적으로 지정하게 되면 득보다 실이 많다. → IEnumerable과 이를 상속하는 IQueryable 등
- 정확히 기술된 타입 자체보다는 타입을 유추할 수 있는 변수의 이름이 더 큰 도움이 된다.
var를 사용했는데 더 어지러운 경우
- 메서드 이름만으로 반환 타입을 짐작하기 어려운 경우가 있는데, 이럴때 var의 타입이 무엇인지 알기 어려워진다.
- C#이 제공하는 내장 숫자 타입들은 매우 다양한 형변환 기능을 가지고 있고, 정밀도도 각각 다르기 때문에 이와 var를 함께 사용할 때는 주의해야 한다.
코드를 읽을 때 지역변수의 타입을 명확히 유추할 수 없고 모호함을 불러일으킬 가능성이 있다면 차라리 타입을 명시적으로 선언하는 것이 좋다. 하지만 대부분의 경우에 변수의 이름을 통해서 그 역할을 명확하게 드러내도록 코드를 작성하는 것이 훨씬 낫다. 다만 내장 숫자 타입을 선언할 때는 명시적으로 타입을 선언하는 편이 낫다.
아이템 2: const보다는 readonly가 좋다
런타임 상수: readonly
컴파일 상수: const
컴파일타임 상수
- 런타임 상수보다 약간 더 빠르지만 유연성이 떨어짐
- 메서드 내부에서도 선언할 수 있음
- 상수형 변수가 사용되는 위치가 실질적인 값으로 치환됨
- 그러므로 내장 자료형(정수형, 실수형)이나 enum, string에 대해서만 사용 가능
- static이므로 항상 동일한 값
런타임 상수
- 메서두 내부에서 선언할 수 없음
- 컴파일타임 상수와 다르게 실질적인 값으로 대체되지 않고 상수에 대한 참조자가 위치하게됨
- 생성자 호출 이후 값을 변경할 수 없지만 생성자 내에서는 값이 할당될 수 있음
- 타입의 인스턴스 별로 서로 다른 값을 가질 수 있음
Assembly A
public class UsefulValues
{
public static readonly int StartValue = 5;
public const int EndValue = 10;
}
Assembly B
for (int i = UsefulValues.StartValue; i < UsefulValues.EndValue; i++)
{
Console.WriteLine("Value is {0}", i);
}
만약 위 Assembly A, B가 포함된 코드에서 A의 StartValue, EndValue를 수정 후 A만 컴파일한다면 B의 EndValue는 컴파일타임 상수라 값이 상수로 고정되어있어 for문이 제대로 동작하지 않을 수 있다.
명명된 매개변수(named parameter)나 선택적 매개변수(optional parameter)도 상수의 특성과 연관이 있기 때문에 매우 신중하게 접근해야 한다.
아이템 3: 캐스트보다는 is, as가 좋다
- 형변환 가능성 여부는 is로, 형변환은 as로 해주는 것이 좋다
- 컴파일러는 객체가 런타임에 어떤 타입인지를 알 방법이 없다.
- as와 is 연산자는 런타임에 정확한 타입의 변환이 가능할 때에만 형변환을 수행한다.(같은 타입이거나 상속한 타입이 아니라면 컴파일에러)
- as연산자로 형변환시 try/catch문을 사용하지 않아도 된다.
- 단, as연산자는 value타입에 대해서는 동작하지 않는다. (value는 null이 될 수 없기 때문)
as연산자와 cast 연산자의 가장 큰 차이점은 사용자가 정의한 형변환 연산자를 어떻게 다루는가 하는 것이다. as나 is 연산자는 런타임에 객체의 형변환이 가능한지 확인하기 위해서 사용자가 정의한 형변환 연산자를 전혀 고려하지 않는다. → 모호함 없이 일관된 동작을 보장한다.
정확한 타입비교를 위해서는 GetType()을 이용하자. 이는 as보다 매우 엄격한 비교를 수행한다.
아이템4: string.Format()을 보간 문자열로 대체하라
C#6.0부터 도입된 문자열 보간 기능을 사용해보자
장점
- 코드 가독성 대폭 향상
- 정적 타입 검사 수행 → 개발자 실수 방지
- 기존 방식에 비해 문자열을 생성하기 위한 표현식이 더 풍성
팁
- 보간 문자열을 사용하면 컴파일러는 param을 이용하여 object배열을 전달하는 기종 포매팅 함수를 호출하도록 코드를 생성한다. 그런 경우 사전에 문자열로 값을 변경하여 박싱되는 것을 피할 수 있다
- 문자열 보간의 결과는 문자열일 뿐이다. SQL 명령을 만들 때 문자열 보간 기능을 사용하는 것은 그리 추천할 만한 방식이 아니다.
'공부 > 개발독서 - c++, c#' 카테고리의 다른 글
[EMC++] 소개 (0) | 2023.11.04 |
---|---|
[effective C#] 1장 C# 언어 요소 (아이템 8 ~ 10) (0) | 2022.04.24 |
[effective C#] 1장 C# 언어 요소 (아이템 5 ~ 7) (0) | 2022.04.17 |