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!");
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.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이다.
}
record Type
1. 정의
C# 9.0 에서 가장 두드러진 변화는 record 타입 을 새로 도입한 것이다. 지금까지는 C#/.NET 에서는 struct를 사용하는 Value Type 과 class를 사용하는 Reference 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.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.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; }
}
향상된 패턴 매칭(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.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.5. 단순 타입 패턴(Simple type pattern) 사용 예제
switch 식에서 흔히 사용하지 않는 변수를 (_) 로 표시한다. 기존에는 이 밑줄(discard parameter 라고 부른다.)생각할 수 없었다. C# 9.0에서는 생략이 가능하다. Check() 메서드에서 이전에는 그 외를 표시하려면 (_) 기호를 사용해야 했지만, 생략했다.
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; }
}
'프로그래밍 언어 > C#' 카테고리의 다른 글
[C#] 고성능 서버 - __FILE__, __LINE__ 대체제 (0) | 2024.01.04 |
---|---|
[C#] 8.0 새로운 기능 (0) | 2023.10.04 |
[C#] 4.0 필수 매개변수 및 선택적 매개변수 (0) | 2023.09.22 |
[C#] 생성자와 상속 (0) | 2023.09.22 |
[C#] 하나의 클래스의 모든 상속클래스 (자식클래스) 가져오기 (0) | 2023.09.21 |