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;
            }
        }
    }
    신간 소식 구독하기
    뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.