C# 6.0의 새로운 기능들

안녕하세요. :)

오래전부터 닷넷 파운데이션C# 6.0의 기능을 확정하고 개발에 착수했었습니다. 이제 막바지 작업인것으로 보여, 머지않아 차세대 C#을 만나볼 수 있을 듯 합니다. 그래서 오늘은 C# 6.0의 큰 특징들과 차기 C# 7.0에 대한 이슈를 정리하는 포스트를 써 보았습니다.

이 포스트는 2015-07-05 기준으로 작성되었으며 자잘한 특징들은 변화할 수 있음을 알려드립니다.

C# 6.0은 기본적으로 구버전의 C#보다 코드의 반복을 줄이고 간결하게 만드는데 도움을 주는 기능 위주로 추가되었습니다.

1) 자동 속성(auto-property)의 기본값을 설정할 수 있습니다.

public class Customer
{
    public string First { get; set; } = "Jane";
    public string Last { get; set; } = "Doe";
}

auto-property은 컴파일러가 Backing Field를 만들어주는 property입니다. C# 6.0에서는 이 property에 기본값을 지정할 수있게 되었는데, 기존에 쓰시던 auto-property 뒤에 =(equal)을 붙이고 값을 할당하면 초기값으로 설정됩니다.

2) Expression-bodied function members

간단한 계산식에 의해 표현되는 속성을 Lambda Arrow(=>)를 통해 더 간결하게 나타낼 수 있습니다.

public string Name => FirstName + " " + LastName;
public int Size => Width * Height;

이런 특징은 함수와 연산자 오버로딩에서도 동일하게 적용됩니다.

public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public static implicit operator string(Person p) => p.First + " " + p.Last;

3) Using static

기존 C#에서의 using 구문은 ‘네임스페이스를 사용한다’라는 의미에 그쳤다면, 6.0부터는 추가된 using static구문으로 정적 함수를 더 사용하기 쉽게 바뀌었습니다.

using static System.Console;
using static System.Math;
using static System.DayOfWeek;

class Program
{
    static void Main()
    {
        WriteLine(Sqrt(3*3 + 4*4));
        WriteLine(Friday - Monday);
    }
}

물론 함수명이 겹친다면 Full-Name으로 명시해야 할 듯 합니다.

4) Null-conditional operators

C# 개발을 해보신 분이라면, 당연히 if문에 null체크를 위한 코드가 잔뜩 쓰여있을 것입니다. 이런 문제점을 해결해주기 위해 Null 조건 연산자라는 것이 도입되었습니다. Null 조건 연산자는 ‘?’로 쓰며 ‘?’앞의 객체가 null이 아니라면 뒤의 함수를 실행하는 형태입니다.

int? count = row?.Count;
int? peopleAge = people?[0]?.getAges();
// 배열이 먼저 null인지 체크 후, 인덱스 0번이 null인지 체크 후 함수 실행.

C#에서 null을 값에 담으려면, INullable를 상속받아야하는데, 그렇지 않은 클래스와 기본 구조체들 int, float… 등은 ‘??’ 연산자를 통해 null일때 기본적으로 담을 값을 설정 가능합니다. 혹은 그러한 구조체들 뒤에 ‘?’를 붙혀 Nullable하다는 것을 지정할 수도 있습니다.

int count = row?.Count ?? 0;

5) Exception Filter

닷넷 계열 언어에는 오래전부터 있었던 기능으로, try-catch에서 잡아낼 예외에 조건을 정해줄 수 있었습니다.

try
{
    // working...
}
catch(Exception ex) if (ex.ErrorCode == 1)
{
    // Booom!
}

위 코드는 발생한 예외 중 예외 객체의 멤버 ErrorCode가 1인 예외만 잡아내는 코드입니다.

6) nameof 예약어 추가

nameof 연산자는 함수명이나 객체의 이름, Type를 반환합니다. 예외처리, 로깅할 때 함수명을 하드코딩하지 않아도 됩니다.

Console.WriteLine("{0} : {1}", nameof(people.age), people.age);

7) catch/finally 블록에서 await 사용

너무 자주 알려져있는 6.0의 특징입니다.

끝으로 C# 7.0에 기여하고 싶으신 분은 Github에 가셔서 자세히 알아보세요!!