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;
}
}
}