C# 8.0 버전의 새로운 기능 열 가지가 적용된 코드 작성하기
Program.cs 파일에 200줄 가까이 되는 다음 내용을 입력한 후 실행해 보세요.
C# 8.0 버전의 새로운 기능 열 가지: DotNet\SeeSharp.Eight\Program.cs
using System; using System.Collections.Generic; using System.Threading.Tasks; namespace SeeSharp.Eight { //인터페이스 public interface IEmployee { public string Name { get; } public decimal Salary { get; } //[!] C# 8.0: Default interface members public string Id { get => $"{Name}[{this.GetHashCode()}]"; } } //클래스 public class Person { #nullable disable public string Name { get; } public Person(string name) => Name = name; //[!] public string FirstName { get; set; } public string MiddleName { get; set; } public string LastName { get; set; } #nullable enable public Person(string first, string last) { FirstName = first; MiddleName = null; LastName = last; } public Person(string first, string middle, string last) { FirstName = first; MiddleName = middle; LastName = last; } } //Abstract 클래스 public abstract class Employee : Person, IEmployee { public Employee(string name, decimal salary) : base(name) => Salary = salary; public decimal Salary { get; protected set; } } public class Professor : Employee, IEmployee { public string Topic { get; } public Professor(string name, decimal salary, string topic) : base(name, salary) => Topic = topic; //Deconstruct 메서드 public void Deconstruct(out string name, out string topic) => (name, topic) = (Name, Topic); //인덱스 및 범위 //public string Id => $"{Name}[{Topic[0..3]}]"; public string Id => $"{Name}[{Topic[..3]}~{Topic[^3..^0]}]"; } public class Administrator : Employee { public string Department { get; } public Administrator(string name, decimal salary, string department) : base(name, salary) => Department = department; } public static class Service { #nullable disable static Person[] people = null; #nullable enable static Service() { //null 병합 할당 연산자: ??= people ??= new Person[] { new Professor("RedPlus", 1_ _ _ _ _ _000, "Computer Science"), new Administrator("Taeyo", 2_000, "ABC"), new Professor("Itist", 3_000, "Computer Science") }; } public static IEnumerable<IEmployee> GetEmployees() { foreach (var person in people) { if (person is IEmployee employee) { yield return employee; } } } //C# 8.0 비동기 스트림(Asynchronous streams) public static async IAsyncEnumerable<IEmployee> GetEmployeesAsync() { foreach (var person in people) { await Task.Delay(500); if (person is IEmployee employee) yield return employee; } } } class Program { static async Task Main(string[] args) { //C# 8.0 - 정적 로컬 함수(Static Local Function) static void Print(string message) => Console.WriteLine(message); //ⓐ 동기 방식 출력 foreach (var employee in Service.GetEmployees()) { Print($"Name : {employee.Name}"); } Print("========================================"); foreach (var employee in Service.GetEmployees()) { //패턴 매칭: C# 7.0 if (employee is Administrator administrator && administrator.Department is "ABC") { Print($"Administrator : {administrator.Name}"); } } Print("========================================"); //ⓑ 비동기 방식 출력 await foreach (var employee in Service.GetEmployeesAsync()) { //패턴 매칭: C# 8.0 속성 패턴 if (employee is Professor { Topic: "Computer Science", Name: var name } professor) { Print($"Professor : {name} ({professor.Id})"); } } await foreach (var employee in Service.GetEmployeesAsync()) { //패턴 매칭: C# 8.0 위치 패턴 if (employee is Professor(var name, "Computer Science") professor) { Print($"Professor : {name} ({professor.Id})"); } } //C# 8.0 - nullable 참조 형식 var red = new Person("YJ", "Park"); var length = GetMiddleNameLength(red); Console.WriteLine(length); //0 //Switch 식 Print("========================================"); await foreach (var employee in Service.GetEmployeesAsync()) { Console.WriteLine(GetDetails(employee)); } static string GetDetails(IEmployee person) { return person switch { Professor p when p.Salary > 1_000 => $"{p.Name} - {p.Topic} - Big", Professor p => @$"{p.Name} - {p.Topic}", Administrator a => $"{a.Name} - {a.Department}", _ => $@"Who are you?" }; } } static int GetMiddleNameLength(Person? person) { //is { } if (person?.MiddleName is { } middle) return middle.Length; return 0; } } }