[C#] C# 6.0

사실 내가 맨처음 배웠던 건 4.0이었는데, 4.0에는 dynamic이나 람다같은게 추가된걸로 알고…
5.0은 잘 모르겠는데 async, await등등 이었던 걸로 기억하고…
오늘 VS를 켰는데 C# 6.0에 관한 내용이 있길래 들어가봤는데 포스팅은 4월 29일에 된거 (…)

그래서 살펴봤더니 뭔가 이건 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

일단 출처

  1. 읽기 전용 프로퍼티
  2. get만 가지고 있는 프로퍼티는 선언과 동시에 초기화하거나 생성자에서 초기화가 가능하다.(readonly와 비슷하게) 이것은 private set이 있는 것과 차이가 있는게, get만 가지고 있으면 동일 클래스 내부에서라도, 생성자를 제외한 곳에서는 set을 할 수 없다.
    [code language=”csharp”]
    class Test
    {
    public int Number { get; } = 5; // 가능

    public Test(int n)
    {
    Number = n; // 가능
    }

    public void Func(int n)
    {
    Number = n; // 불가능
    }
    }
    [/code]

  3. using static
  4. using static을 이용하면 클래스의 static멤버를 클래스 이름 없이 바로 사용할 수 있게 된다. 가령, Math.Sqrt는 기존에는
    [code language=”csharp” gutter=”false”]
    Math.Sqrt(4);
    [/code]
    으로 사용하였지만, using static을 이용하면 다음과 같이 사용할 수 있다.
    [code language=”csharp” gutter=”false”]
    using static System.Math;

    Sqrt(4);
    [/code]

  5. String Interpolation
  6. …. 이게 들어올 줄은 꿈에도 몰랐다. 루비에서나 사용하던건데… 이것을 이용하면 string.Format을 사용하지 않아도 되는데.. 그렇게 세부적인 설정까지는 못해줄 것 같다.(가령 3자리에 맞춰서 숫자를 출력한다던가하는.. 서식지정자도 string.Format에서 쓰던 그대로 쓰면 된다)
    Interpolation을 사용하는 문자열 앞에는 $를 붙인다.

    가령 string.Format을 사용하면 다음과 같은데,
    [code language=”csharp” gutter=”false”]
    string.Format("({0},{1})", x, y);
    [/code]

    interpolation을 이용하면 다음으로 끝난다.
    [code language=”csharp” gutter=”false”]
    $"({x},{y})";
    [/code]
    (최신 스펙이다보니 하이라이팅이 잘 안된다…)

  7. Expression-bodied Method
  8. 메서드의 구현을 람다식으로 할 수 있다.

  9. 인덱서 초기화
  10. 인덱서가 있는 타입(대표적으로 Dictionary)의 초기화를 실행할 수 있다.
    [code language=”csharp”]
    Dictionary<string, string> dict = new Dictionary() { ["Hello"] = "World", ["C#"] = "6.0" };
    Console.WriteLine(dict["Hello"]); // World 를 출력
    Console.WriteLine(dict["C#"]); // 6.0 을 출력
    [/code]

  11. null 조건 oeprator
  12. 가령 다음과 같은 상황이 있다고 하자.

    • obj라는 객체가 있는데 이게 null인지 아닌지는 모른다.
    • obj 안에 있는 num이 음수면 num을 3으로 바꾼다.

    그래서 원래 알던데로 짜면 다음과 같이 짠다.
    [code language=”csharp”]
    if(obj != null && obj.num < 0)
    obj.num = 3;
    [/code]
    그런데 null-conditional operator을 이용하면 다음과 같이 바뀐다.
    [code language=”csharp”]
    if(obj?.num < 0)
    obj.num = 3;
    [/code]
    Dictionary라면 더 복잡하게 사용할 수 있다.
    만약 Dictionary 객체 dict가 null인지는 모르겠고, dict안에 “Hello”라는 키에 대응하는 Value가 null인지 아닌 지는 모르겠는데, 그것의 길이가 5라면 그 Value를 출력한다라는 것을 생각해보면,
    [code language=”csharp”]
    if(dict != null &&
    dict["Hello"] != null &&
    dict["Hello"].Length == 5)
    Console.WriteLine(dict["Hello"]);
    [/code]
    인데, 얘를 줄이면 다음과 같다.
    [code language=”csharp”]
    if(dict?["Hello"]?.Length == 5)
    Console.WriteLine(dict["Hello"]);
    [/code]

    최근에 바인딩을 하면서 뷰모델을 만들 때, INotifyPropertyChanged 인터페이스를 상속하고 나서, PropertyChanged 이벤트를 상속받고, 프로퍼티의 set에 OnPropertyChanged라고 해서 어쩌구저쩌구 막 했는데, OnPropertyChanged는 다음과 같이 생겼었다.

    [code language=”csharp”]
    protected void OnPropertyChanged(string propertyName)
    {
    if(PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    [/code]
    이것도 Null조건 operator를 이용해서 바꿀 수 있다.
    [code language=”csharp”]
    protected void OnPropertyChanged(string propertyName)
    {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    [/code]
    위에서 설명은 자세히 안했지만, 메서드의 몸체를 람다식으로 바꿀 수 있다. 따라서 다시 줄이면
    [code language=”csharp”]
    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    [/code]
    가 된다.

그 이후에는 async, await내용이라 모르는… (…)

위에 있는 것을 한꺼번에 집약한 예제를 봅시다. (영상의 예외 비슷하지만..)

[code language=”csharp”]
public class Point
{
public double X { get; private set; }
public double Y { get; private set; }
public double? Angle { get; }

public double? Dist
{
get { return Sqrt(X * X + Y * Y); }
set
{
if (Angle.HasValue && value.HasValue)
{
X = value.Value * Cos(Angle.Value);
Y = value.Value * Sin(Angle.Value);
}
}
}

public Point(double x = 0, double y = 0, double? dist = null, double? angle = null)
{
if (dist.HasValue && angle.HasValue)
{
Angle = angle;
Dist = dist;
}
else
{
X = x;
Y = y;
if (y == 0)
Angle = Atan(x * double.PositiveInfinity);
else
Angle = Atan(x / y);
}
}

public override string ToString() => $"({X}, {Y}) [Angle : {Angle}, Distance : {Dist}]";
}
[/code]

위 코드는 조금 향상된 2차원 점 클래스이다.

[code language=”csharp”]
static void Main(string[] args)
{
Point p = new Point(dist: 30, angle: PI/2);
Point p2 = new Point(4, 4 * Sqrt(3));

Console.WriteLine(p); // 동경의 길이가 30이고 각이 45˚인 점
p.Dist = 5; // 동경의 길이를 5로 줄인다
Console.WriteLine(p); // 동경의 길이가 5이고 각이 45˚인 점
Console.WriteLine(p2); // (4, 4sqrt(3))
}
[/code]

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다