2022. 3. 21. 22:11ㆍLanguages/C#
튜플 (Tuple)
여러 필드를 담을 수 있는 구조체로, 역시 값 형식이다.
읽기 전용이 아니므로, 튜플 구성 필드의 값 변경이 가능하다.
구조체와 달리, 튜플은 형식 이름이 없다. 그렇기 때문에 즉석에서 사용할 복합 데이터 형식을 선언할 때 적합하다.
명명되지 않은 튜플(Unnamed Tuple)
다음과 같이 필드의 이름을 지정하지 않는 튜플을 명명되지 않은 튜플(Unnamed Tuple)이라고 한다.
var tuple = (123, 789);
튜플은 괄호 사이에 두 개 이상의 필드를 지정함으로써 만들어 진다. 위 예제처럼 생성한 경우,
C# 컴파일러는 자동적으로 123을 Item1이라는 필드에 담고, 789를 Item2라는 필드에 담는다.
var tuple = (123, 789);
Console.WriteLine($"{tuple.Item1}, {tuple.Item2}"); // 123, 789 출력
튜플이 System.ValueTuple 구조체를 기반으로 만들어지기 때문에 위와 같이 담긴다고 한다.
명명된 튜플(Named Tuple)
필드명:의 꼴로 필드의 이름을 지정하여 선언할 수도 있다.
var tuple = (Name:"DaekYou", Age: 25);
Console.WriteLine($"{tuple.Name}, {tuple.Age}"); // DaekYou, 25 출력
튜플 분해하기
다음과 같이 튜플을 분해할 수도 있다.
var tuple = (Name:"DaekYou", Age: 25);
var (name, age) = tuple; // 분해
Console.WriteLine($"{name}, {age}"); // DaekYou, 25 출력
특정 필드를 무시하고 싶다면, _를 사용하면 된다.
var tuple = (Name:"DaekYou", Age: 25);
var (name, _) = tuple; // Age 필드는 무시
Console.WriteLine($"{name}"); // DaekYou 출력
다음과 같이 여러 변수를 단 번에 생성하고 초기화하여 분해하는 것도 가능하다.
var (name, age) = ("DaekYou", 25);
Console.WriteLine($"{name}, {age}"); // DaekYou, 25 출력
switch 문 또는 switch 식의 분기 조건에 활용 해보기
튜플이 분해가 가능한 이유는 분해자(Deconstructor)를 구현하고 있기 때문이다.
분해자를 구현하고 있는 객체를 분해한 결과를 switch 문이나 switch 식의 분기 조건에 활용할 수 있다.
이것을 위치 패턴 매칭(Positional Pattern Matching)이라고 한다.
식별자나 데이터 형식이 아닌, 분해된 요소의 위치에 따라 값이 일치하는지를 판단하는 것이다.
var daekYou = (job:"학생", age: 17);
var discountRate = daekYou switch
{
("학생", int n) when n < 18 => 0.2, // 학생 & 18세 미만
("학생", _) => 0.1, // 학생 & 18세 이상
("일반", int n) when n < 18 => 0.1, // 일반 & 18세 미만
("일반", _) => 0.05, // 일반 & 18세 이상
_ => 0,
};
/* C# 8.0 이상 버전에서만 사용 가능한 문법인 것 같다. */
다음과 같이 메소드를 통해 활용할 수도 있다.
static double GetDiscountRate(object client)
{
return cleint switch
{
("학생", int n) when n < 18 => 0.2, // 학생 & 18세 미만
("학생", _) => 0.1, // 학생 & 18세 이상
("일반", int n) when n < 18 => 0.1, // 일반 & 18세 미만
("일반", _) => 0.05, // 일반 & 18세 이상
_ => 0,
};
}
static void Main(string[] args)
{
var alice = (job:"학생", age: 17);
var bob = (job:"학생", age: 23);
var charlie = (job:"일반", age: 15);
var dave = (job:"일반", age: 21);
Console.WriteLine($"alice : {GetDiscountRate(alice)}"); // alice : 0.2
Console.WriteLine($"bob : {GetDiscountRate(bob)}"); // bob : 0.1
Console.WriteLine($"charlie : {GetDiscountRate(charlie)}"); // charlie : 0.1
Console.WriteLine($"dave : {GetDiscountRate(dave)}"); // dave : 0.05
}
명명되지 않은 튜플과 명명된 튜플은 필드의 수와 형식이 같으면 할당 가능하다.
var unnamed = ("DaekYou", 25); // (string, int)
var named = (Name: "CoCo", Age: 1); // (string, int)
named = unnamed;
Console.WriteLine($"{named.Name}, {named.Age}"); // DaekYou, 25 출력
named = ("Rengar", 5);
unnamed = named;
Console.WriteLine($"{unnamed.Item1}, {unnamed.Item2}"); // Rengar, 5 출력
- 이 글은 <이것이 C#이다> 책을 바탕으로 공부한 글입니다.
'Languages > C#' 카테고리의 다른 글
[C#] 객체지향의 꽃, 인터페이스(Interface) - 2편 (0) | 2022.03.22 |
---|---|
[C#] 객체지향의 꽃, 인터페이스(Interface) - 1편 (2) | 2022.03.22 |
[C#] 구조체(Structure)에 대해 알아보자! (0) | 2022.03.21 |
[C#] 확장 메소드 (Extension Method) (0) | 2022.03.21 |
[C#] 중첩 클래스(Nested Class)와 분할 클래스(Partial Class) (2) | 2022.03.21 |