C# 9.0 새로운 기능 소개
- C#
- 2021. 4. 28. 19:24
참조
- .NET Conf 2021 x Seoul, Day 2 - C# 9.0 새로운 기능 소개 (박용준) (https://youtu.be/VJSYk_x_zJc?t=750)
- C# 9.0 설명 블로그(https://www.csharpstudy.com/latest/CS9-record.aspx)
- C# 9.0의 새로운 기능(https://docs.microsoft.com/ko-kr/dotnet/csharp/whats-new/csharp-9)
C# 9.0 개발 환경 구축
- Visual Studio 2019
- .NET CLI(.NET 5.0 SDK)
- dotnet --version
- dotnet --list-sdks
- dotnet new console --help
- dotnet new console -f net5.0
- C# 프로젝트 속성에서 Application -> Target framework을 [+.NET 5+] 으로 설정해야 C# 9.0 기능 사용 가능합니다.
C# 9.0 추가된 기능들
- 최상위 프로그램(Top-Level Programs)
- init accessor
- record Type
- 향상된 패턴 매칭(Pattern matching)
최상위 프로그램 (Top-Level Programs)
1. 정의
- C# 프로그램은 Main() 정적 메서드에서부터 프로그램 시작하며, C# 프로젝트 생성하면 항상 이 Main() 메서드를 자동으로 생성합니다.
- 프로그래밍에서 이를 보통 엔트리 포인트(Entry point) 라 부릅니다.
- 프로그래밍을 처음 시작하는 분들은 Main() 엔트리 포인트 부분의 이해가 어렵습니다.
- 때문에 C# 9.0에서 이러한 제약을 없애고 바로 C# 문장을 사용할 수 있는 기능을 제공합니다.
- 이를 최상위 프로그램(Top-Level Program) 이라 부릅니다.
2. 사용 예제
2.1. C# 9.0 Top-Level Program 적용 이전
using System;
namespace Csharp_9._0Test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
2.2. C# 9.0 Top-Level Program 적용 이후
using static System.Console;
WriteLine("Hello World!");
2.3. Result (출력 결과)
- Main() 메서드가 없어도, "Hello World!" 제대로 출력
- Hello World!
init accessor
1. 정의
- C# 9.0 에서 init 키워드가 새로 추가되었습니다.
- init은 객체의 속성을 처음 초기화 하는 용도로 사용됩니다.
- init 키워드는 해당 속성이 한번 설정되면, 그 이후에 변경할 수 없는 기능을 제공하여 Immutable(불변) 속성 만드는데 사용됩니다.
2. 사용 예제
2.1. 일반적인 속성 초기화 방법
- 초기에 Sponsor 객체에서 DisplayName 속성을 Red 문자열로 초기화 진행
- 그 다음에 DisplayName 속성을 RedPlus 문자열로 다시 저장 진행
- 결과적으로 맨 마지막에 저장된 문자열인 RedPlus 문자열이 출력
var sponsor = new Sponsor //Sponsor 객체 생성
{
Id = 1,
DisplayName = "Red"
};
sponsor.DisplayName = "RedPlus"; //mutable(변경가능)
DisplayData(sponsor);
static void DisplayData(Sponsor sponsor) =>
System.Console.WriteLine($"{sponsor.Id} - {sponsor.DisplayName}");
struct Sponsor
{
public int Id { get; set; }
public string DisplayName { get; set; }
}
2.2. 일반적인 속성 초기화 방법 Result (출력 결과)
2.3. init accessor 초기화 방법
- 프로퍼티에서 set 대신 init 키워드 사용
- 처음 객체 생성에서 초기화 진행 후, init 키워드로 설정된 속성을 다시 초기화 할 경우 에러 발생
- 즉, init 키워드로 설정한 속성은 변경 불가합니다.
var sponsor = new Sponsor //Sponsor 객체 생성
{
Id = 1,
DisplayName = "Red"
};
//sponsor.DisplayName = "RedPlus"; //immutable(변경불가)
DisplayData(sponsor);
static void DisplayData(Sponsor sponsor) =>
System.Console.WriteLine($"{sponsor.Id} - {sponsor.DisplayName}");
struct Sponsor
{
public int Id { get; init; }
public string DisplayName { get; init; } //init은 초기화 전용 Setter 입니다.
}
2.4. init accessor 초기화 방법 Result (출력 결과)
- sponsor 객체 생성 후, DisplayName 속성에 처음 초기화 했던 Red 내용 출력
- sponsor.DisplayName = "RedPlus"; 위처럼 다시 초기화 불가능
record Type
1. 정의
- C# 9.0 에서 가장 두드러진 변화는 record 타입 을 새로 도입한 것입니다.
- 지금까지는 C#/.NET 에서는 struct를 사용하는 Value Type 과 class를 사용하는 Referecne Type 이 있었습니다.
- C# 9.0 에서는 Immutable 값 데이터를 갖는 record 타입 을 추가하였습니다.
- record 타입 은 객체 내의 멤버가 변하지 않는 Immutable Reference Type 을 만들기 위한 것 입니다.
2. 사용 예제
2.1. record Type 기본 사용 예제
- 기존의 class 키워드 자리에 record 라는 타입의 Subscriber 생성
- Subscriber 의 속성은 Title, Duration 2개의 속성을 갖습니다.
- 2개의 속성 모두 init 속성으로 immutable 형태입니다.
var subscriber = new Subscriber { Title = "Visual", Duration = 2 };
System.Console.WriteLine(subscriber);
//Record 클래스 생성
record Subscriber
{
public string Title { get; init; }
public int Duration { get; init; }
}
2.2. record Type Result(출력 결과)
2.3. record Type 간편 구문 예제
- record Subscriber(string Title, int Duration); 이와같이 Title, Duration 2개의 속성을 생성자 형태로 표현 가능합니다.
- (1)과 (2)는 같은 구문입니다.
- 다만 (2)번이 (1) 번 구문의 간편 구문으로서 사용법은 동일합니다.
//(1)
record Subscriber
{
public string Title { get; init; }
public int Duration { get; init; }
}
//(2)
record Subscriber(string Title, int Duration);
- record Type 간편구문 예제
var subscriber= new Subscriber("Visual2", 3);
System.Console.WriteLine(subscriber);
//Record 타입 간편 구문(Syntax Sugar)
record Subscriber(string Title, int Duration);
2.4. record Type 간편 구문 Result(출력 결과)
2.5. record Type with 표현식 예제
- record Type은 immutable 형태로서 불변 상태를 나타냅니다.
- 그러나 record Type을 변경하고 싶다면 with 키워드를 사용하면 됩니다.
var subscriber = new Subscriber { Title = "Visual", Duration = 2 };
var vip = subscriber with { Title = "VIP" }; // with 구문을 이용하면 record 클래스 속성 변경 가능
System.Console.WriteLine($"변경 전 출력");
System.Console.WriteLine(subscriber);
System.Console.WriteLine($"변경 후 출력");
System.Console.WriteLine(vip); //with 구문으로 Title = Visual -> VIP 로 변경
//record 타입
record Subscriber
{
public string Title { get; init; }
public int Duration { get; init; }
}
2.6. record Type with 표현식 Result(출력 결과)
- record Type으로 생성된 subscriber 객체를 하나 생성하여 Title = "Visual", Duration = 2 로 설정합니다.
- vip 라는 객체 하나를 생성하고, 기존 subscriber 에서 Title 만 Visual -> VIP 로 변경을 시킵니다.
- record 타입 내용 변경할 땐 with 키워드를 사용합니다.
- 변경 전 subscriber 객체는 Title 이 "Visaul" 로 출력이 되고, vip 객체의 Title은 변경된 내용인 "VIP" 가 출력됩니다.
향상된 패턴 매칭(Pattern matching)
1. 정의
- 패턴 매칭은 C# 6.0에서 처음 도입된 개념입니다.
- C# 8.0 에서는 switch 식, 속성 패턴, 튜플 패턴, 위치 패턴, 재귀 패턴 등 다양한 기능이 추가되었습니다.
- C# 9.0 에서는 부등호를 사용하여 비교 연산이 가능한 관계 패턴(Relation pattern), and, or, not 등과 같은 논리 패턴 (Logical pattern) , 단순 타입 패턴(Simple type pattern) 등이 새롭게 추가되었습니다.
2. 사용 예제
2.1. 관계 패턴(Relational pattern) 사용 예제
- C# 9.0 에서는 switch 식에 >, <, >=, <= 등과 같은 관계 연산자를 사용할 수 있습니다.
- 아래 예제는 GetGrade() 메서드에서 관계 연산자 패턴을 적용해 보았습니다.
// 관계 패턴 (Relational pattern)
//Student 객체 생성
Student stu = new Student()
{
Name = "홍길동",
Score = 78
};
System.Console.WriteLine($"{stu.Name} 의 등급은 {GetGrade(stu)} 입니다.");
string GetGrade(Student stu)
{
//관계패턴
string grade = stu.Score switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F",
};
return grade;
}
class Student
{
public string Name { get; set; }
public int Score { get; set; }
}
2.2. 관계 패턴(Relational pattern) 사용 예제 Result(출력 결과)
2.3. 논리 패턴(Logical pattern) 사용 예제
- C# 9.0 에서는 switch 식에서 and, or, not 등과 같은 논리 연산자를 사용할 수 있습니다.
- 관계 연산자와 논리 연산자는 혼합 해서 사용 가능합니다.
// 논리 패턴 (Logical pattern)
//Student 객체 생성
Student stu = new Student()
{
Name = "홍길동",
Score = 94
};
Student stu2 = new Student()
{
Name = "이순신",
Score = 56
};
System.Console.WriteLine($"{stu.Name} 은 {GetValue(stu)} 입니다.");
System.Console.WriteLine($"{stu2.Name} 은 {GetValue(stu2)} 입니다.");
string GetValue(Student stu)
{
//논리패턴 & 관계패턴 혼합
string grade = stu.Score switch
{
> 79 and < 100 => "우등생",
> 0 and < 60 => "나머지학생"
};
return grade;
}
class Student
{
public string Name { get; set; }
public int Score { get; set; }
}
2.4. 논리 패턴(Logical pattern) 사용 예제 Result(출력 결과)
2.5. 단순 타입 패턴(Simple type pattern) 사용 예제
- switch 식에서 흔히 사용하지 않는 변수를 (_) 로 표시합니다.
- 기존에는 이 밑줄(discard parameter 라고 부른다.)생각할 수 없었습니다.
- C# 9.0에서는 생략이 가능합니다.
- Check() 메서드에서 이전에는 그 외를 표시하려면 (_) 기호를 사용해야 했지만, C# 9.0 부터는 생략 가능합니다.
Duck \_duck = new Duck() { Name = "오리", Sound = "꽥꽥" };
Dog \_dog = new Dog() { Name = "강아지", Sound = "멍멍" };
System.Console.WriteLine($"{\_dog.Name}는 {Check(\_dog)}");
System.Console.WriteLine($"{\_duck.Name}는 {Check(\_duck)}");
string Check(Animal animal)
{
//논리패턴
string result = animal switch
{
Dog d => "Dog",
Cat c => "Cat",
//Animal \_ => ""
Animal => "그 외 동물들입니다."
};
return result;
}
class Animal
{
public string Sound { get; set; }
}
class Dog : Animal
{
public string Name { get; set; }
}
class Cat : Animal
{
public string Name { get; set; }
}
class Duck : Animal
{
public string Name { get; set; }
}
2.6. 단순 타입 패턴(Simple type pattern) 사용 예제 Result(출력 결과)
728x90
'C#' 카테고리의 다른 글
[C# 문법] C# 7.0 에서 편리해진 out 파라미터 사용방법 (0) | 2021.05.23 |
---|---|
MSDN C# 명명지침 (1) | 2021.05.19 |
C# 코딩 규칙(C# 프로그래밍 가이드) (0) | 2021.05.19 |
[C# 문법] LINQ를 이용하여 string[] (문자열 배열) 데이터 조회하기 (0) | 2019.08.15 |
[C# 문법] Linq를 이용하여 Group By 하는 방법 (0) | 2019.08.13 |
이 글을 공유하기