패턴매칭
어떤 식이 특정 패턴과 일치하는지를 검사
선언패턴
- 식이 주어진 형식과 일치하는지 테스트
- 테스트가 성공하면 식을 주어진 형식으로 변환
object foo = 23;
// 1. foo가 int인 경우 2. foo를 int 형식으로 변환하며 bar에 할당
if (foo is int bar)
{
console.WriteLine(bar);
}
형식 패턴
변수 생성 없이 형식 일치 여부만 테스트
object foo = 23;
if(foo is int)
{
Console.WriteLine(foo);
}
상수 패턴
식이 특정 상수와 일치하는지를 검사
var GetCountryCode = (string nation) => nation switch
{
"KR" => 82,
"US" => 1,
"UK" => 44,
_ => throw new ArgumentException("Not supported Code")
};
Console.WriteLine(GetCountryCode("KR")); // 82
Console.WriteLine(GetCountryCode("US")); // 1
Console.WriteLine(GetCountryCode("UK")); // 44
프로퍼티 패턴
식이 속성이나 필드가 패턴과 일치하는지 검사
class Car
{
public string Model {get; set;}
public DateTime ProducedAt {get; set;}
}
static string GetNickname(Car car)
{
var GemerateMessage = (Car car, string nickname) =>
$"{car.Model} produced in {car.ProducedAt.Year} in {nickname}";
if(car is Car {Model:"Mustang", ProductedAt.Year: 1967})
return GenerateMessage(car, "Fastback")l
else
return GenerateMessage(car, "Unknown");
}
static void Main(string[] args)
{
Console.WriteLine(
GetNuckname(
new Car() {Model = "Mustang", ProducedAt = new DateTime(1967, 11, 23)}));
}
관계 패턴
>, >=, ==, != 등 관계연산자를 이용하여 입력받은 식을 상수와 비교
static int IsPassed(double score) => score switch
{
< 60 => false // score가 60보다 작으면 false
_ => true, // 60보다 크면 true
}
논리 패턴
패턴과 패턴을 패턴 논리 연산자로 조합해서 하나의 논리패턴으로 만듦
괄호 패턴
소괄호 ()로 패턴을 감쌈
object age = 30;
if(age is (int and > 19))
Console.WriteLine("Major");
위치 패턴
식의 결과를 분해하고, 분해된 값들이 내장된 복수의 패턴과 일치하는지 검사
Tuple<string, int> itemPrice = new Tuple<string, int>("espresso", 3000);
if(itemPrice is ("espresso", < 5000)) // espresso이고 5000보다 작은지 검사
{
Console.WriteLine("The coffee is affordable.");
}
Var 패턴
null을 포함한 모든 식의 패턴 매칭을 성공시키고, 그 식의 결과를 변수에 할당
// 모든 과목이 60점이 넘고, 평균이 60점 이상인 경우 Pass
var IsPassed =
(int[] scores) => scores.Sum() / scores.Length is var average
&& Array.TrueForAll(scores, (score) => score >= 60)
&& average >= 60;
무시 패턴
var 패턴처럼 모든 식과의 패턴 일치 검사하며, is식 사용 불가, switch 식에서만 사용 가능
var GetCountryCode = (string nation) => nation switch
{
"KR" => 82,
"US" => 1,
"UK" => 44,
_ => throw new ArgumentException("Not supported Code")
};
// KR, US, UK에 모두 일치하지 않기떄문에 _에 매칭
Console.WriteLine(GetCountryCode("JP")); // Not supported Code 출력
목록 패턴
배열이나 리스트가 패턴의 스퀀스와 일치하는지 검사
var match = (int[] array) => array is [int, >10, _];
Console.WriteLine(match(new int[] {1, 100, 3})); // True
Console.WriteLine(match(new int[] {100, 10, 999})); // false
// 두번째 요소 10이 패턴 시퀀스의 요소 >10과 일치하지 않음