C# 7.0 New Features
C# 7.0 새로운 기능 소개
튜플 ( Tuples )
자, C# 7.0에서 새롭게 달라진 튜플들을 알아보도록 하겠습니다.
Before Code
struct infos{ public int age; public string school;}
public infos Getinfo(string name) { ... }
var yosi = Getinfo("Z1젼7rl발ㅈr");
Console.WriteLine($"age: {yosi.age}, school: {yosi.school}");
튜플 반환 타입 ( Tuple return types )
반환 타입이 2개 이상인 함수를 만들 수 있습니다.
after code
public (int age, string school) Getinfo(string name)
{
...
}
var yosi = GetLatLng("Z1젼7rl발ㅈr");
Console.WriteLine($"age: {yosi.age}, school: {yosi.school}");
인라인 튜플 ( Inline tuples )
역시 아래와 같이 하면 인라인도 가능합니다.
var yosi = new (int age, string school) { age = 0 , school = "Go" };
레코드 타입 ( Record types )
이전에는 프로퍼티 떡칠을 하였다면 7.0에서는 그 불편함을 없애주었습니다.
Before Code
public class Point
{
public int X { get ; set ;}
public int Y { get ; set ;}
}
After Code
public class Point (int X = 1, int Y = 2);
하지만 알아두어야할 점이 있습니다.
1. readonly 필드를 가진 get-only 속성으로 생성이 되어 immutable이 되어있습니다.
2. 이 record type은 상속이 됩니다.
3. record type은 IEquatable<> 인터페이스에도 상속이 가능합니다.
4. Tostring 메소드를 이용하여 레코드의 각 멤버와 값을 나열합니다. ex) "Point (X: 1 Y: 2)"
불멸 타입 ( Immutable Types )
값이 바뀌면 안되는 클래스에 대해 사용하는 키워드입니다.
그저 클래스 앞에 immutable 키워드를 넣어주면 됩니다.
public immutable class Point
{
public Point(int x, int y)
{
x = x;
Y = y;
}
public int X { get; }
public int Y { get; }
}
위의 코드로 중간에 변조를 불가능하게 되어 처음부터 끝까지 이 값을 쓸 수 있게 된다.
이런 형식을 대비하여 유용한 문법이 생겼다.
var yosi0 = new Point(1, 3);
var yosi1 = yosi0 with { X = 9 };
기존 인스턴스로부터 값을 바꿔 새로운 인스턴스로 사용하는 것이다.
Non-Null 참조 타입 ( Non-null reference types )
일반적으로 값 형식은 null을 가질 수 없으며, 반드시 기본 값을 가지게 되어 있습니다.
하지만 6.0에서 Nullable<>형식이 생겨 데이터 타입 뒤에 ? 만 붙이면 null을 가질 수 있게 되었습니다.
int a; // non-nullable value type
int? b; // nullable value type
string c; // non-nullable value type
string? d; // nullable value type
non-null 처리를 하려면 데이터 타입 뒤에 ! 를 붙이면 null이 불가능한 참조 변수를 만들 수 있습니다.
이는 제네릭과 클래스에도 적용이 가능합니다.
int a; // non-nullable value type
int? b; // nullable value type
string! c; // non-nullable reference type
string d; // nullable value type
// Dictionary non-nullable reference type
Dictionary<string, List<MyClass>>! myDict;
지역 함수 ( Local Functions )
블록 내에 잠깐 처리를 위해 람다식을 사용했던 분들이라면 아래와 같은 불편함을 겪을 것이라 예상할 수 있습니다.
1. 제네릭 사용 불가능
2. ref 및 out 사용 불가능
3. 가변 인자 사용 불가능
이를 해결할 수 있는 지역 함수 기능을 제공하였습니다.
C# 7.0 에서는 람다식에서 못한 한계를 해결 할 수 있습니다!
public int Calculate(int someInput)
{
int Factorial(int i)
{
if (i <= 1)
return 1;
return i * Factorial(i - 1);
}
var input = someInput + ... // Other calcs
return Factorial(input);
}
그리고 마지막으로 제일 기대되고 제 생각으로는 개쩌는 기능입니다.
패턴매칭 ( Pattern Matching )
C# 7.0에서 나온 재미나고 사용을 하게 된다면 형태에 의한 분기가 편해질거라 예상됩니다.
is 메서드로 매칭이 가능합니다.
상수 매칭
if ( x is 1 )
{
return 1;
}
형태 매칭
if ( x is T t )
{
return 1;
}
x를 T로 캐스팅 한 것이 t에 들어가며 x가 T의 특정 타입일 때에 매치됩니다.
속성 매칭
if ( x is T {X is int, Y is int} )
{
return 1;
}
재귀 매칭
if ( x is T ( var a 1 ) )
{
return 1;
}
또한 switch 문에서도 패턴 매칭이 가능합니다.
class Geometry();
class Triangle(int Width, int Height, int Base) : Geometry;
class Rectangle(int Width, int Height) : Geometry;
class Square(int width) : Geometry;
Geometry g = new Square(5);
switch (g)
{
case Triangle(int Width, int Height, int Base):
WriteLine($"{Width} {Height} {Base}");
break;
case Rectangle(int Width, int Height):
WriteLine($"{Width} {Height}");
break;
case Square(int Width):
WriteLine($"{Width}");
break;
default:
WriteLine("<other>");
break;
}
switch 문을 각 상속된 클래스와 맞는지 비교하여 해당될 때에 해당 케이스 문을 실행할 수 있습니다.
이번 C# 7.0 정말 기대되네요.
https://www.kenneth-truyers.net/2016/01/20/new-features-in-c-sharp-7/
https://www.kenneth-truyers.net/2016/01/25/new-features-in-c-sharp-7-part-2/
https://msdn.microsoft.com/ko-kr/magazine/mt595758.aspx