MS Docs - https://docs.microsoft.com/ko-kr/dotnet/api/system.tuple?view=net-5.0
Tuple : (1개 이상의 구성요소를 가질 수 있는 자료구조)
- Tuple<T1> ~ Tuple<T1, T2, T3, T4, T5, T6, T7> 까지 7개의 오버로드와
- Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>의 8번째 오버로드로 구성되어 있습니다.
- using System을 사용합니다.
8번째 오버로드 : Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
▶ T1 ~ T7까지는 일반적인 사용법과 같고 8번째 요소에는 반드시 Tuple이 들어가야 합니다.
이를 이용해 Tuple을 재귀적으로 물릴 수 있습니다.
▶ Tuple<1 ~ 7, Tuple<1 ~ 7, Tuple<1 ~ 7, Tuple<1 ~ 7, Tuple<1 ~ 7, ... >>>>> 이런식으로 늘립니다.
▶ 생성자에는 매개변수가 필수입니다.
Tuple<int, int> t2 = new Tuple<int, int>(8, 9);
// 매개변수를 넣어서 생성해줘야 한다.
Tuple<int, int, int, int, int, int, int, Tuple<int, int>> t8
= new Tuple<int, int, int, int, int, int, int, Tuple<int, int>>(1, 2, 3, 4, 5, 6, 7, t2);
// T1 ~T7까지는 Item1 ~ Item7로 사용
// 8번째는 Rest로 사용, 8번째 요소인 튜플의 요소인 경우 Tuple.Rest.Item1로 사용
Console.WriteLine(t8.Rest.Item2); // 9
▶ new를 사용한 생성외에도 Tuple.Create()를 사용해 생성 가능합니다.
// 1 ~ 7 일반적인 경우
var t7 = Tuple.Create(1, 2, 3, 4, 5, 6, 7);
// 8개 일때
// Tuple.Create를 사용하면 8번째 인자를 자동으로 튜플로 감싸줍니다.
var t8 = Tuple.Create(1, 2, 3, 4, 5, 6, 7, 8);
// t8 = Tuple<int, int, int, int, int, int, int, Tuple<int>>
// Tuple.Create의 경우
// 만약 8개 이상 사용하기 위해 Tuple.Create를 중첩하여 사용하면 문제가 생깁니다.
var t10 = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(1, 2, 3));
// t10 = Tuple<int, int, int, int, int, int, int, Tuple<Tuple<int, int, int>>>
// 이렇게 8번째 인자에 Tuple이 중첩되어 버립니다.
// t10.Rest.Item1.Item3 이렇게 이상하게 써야합니다.
▶ 대입불가
튜플로 생성한 개체에는 초기화때 넣어준 값 이외에 다른 값을 대입할 수 없습니다.
var t2 = Tuple.Create(1, 2);
t2.item1 = 10; // Error 할 수 없습니다.
<유사>
ValueTuple
▶ 일반 튜플(참조 형식)과 달리 값 형식입니다.
Tuple 형식
https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/value-tuples
▶ C# 7.0 이상에서 사용할 수 있는 ‘튜플’ 기능은 간단한 데이터 구조로 여러 데이터 요소를 그룹화하는 간결한 구문을 제공합니다.
// 튜플'형식'으로 Tuple과는 다릅니다.
// 다음과 같은 간단한 형식으로 사용가능합니다.
(float, int) t2 = (1.3f, 7);
(int, string, float, int) t4 = (8, "서울", 1.3f, 40);
// 8개 이상도 가능합니다.
(int, int, int, int, int, int, int, int, int, int) t10 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 변수이름은 내부적으로 붙여줍니다.
기능
▶ 필드명 설정
// 다음과 같은 방법으로드필드명 설정이 가능합니다.
var t = (Sum: 4.5, Count: 3);
(double Sum, int Count) d = (4.5, 3);
// C# 7.1부터는 필드명을 설정하지 않아도 초기화식 변수이름에서 필드명이 유추됩니다.
var sum = 4.5;
var count = 3;
var t = (sum, count);
Console.WriteLine($"Sum of {t.count} elements is {t.sum}.");
▶ 합성 / 분해
// 할당 ===============================================================================
// 두 튜플형식의 요소 수가 동일하고
// 우측 튜플요소의 형식이 좌측 튜플요소의 형식과 동일하거나 암시적 변환이 가능한 경우 할당이 가능합니다.
(int, double) t1 = (17, 3.14);
(double First, double Second) t2 = (0.0, 1.0);
t2 = t1;
// 분해 ===============================================================================
// 같은 경우
// 튜플형식으로부터 값을 변수로 나누거나 새로운 변수로 만들수 있습니다.
var t3 = ("서울", 36.5f);
{ // 1번
(string city, float Temp) = t3;
}
{ // 2번
var (city, Temp) = t3;
}
{ // 3번
string city;
float Temp;
(city, Temp) = t3;
}
// 여러 방법으로 분해할 수 있습니다.
▶ 어떤 적은 매개변수를 사용하는 클래스가 필요할때
굳이 클래스를 만들지 않고 Tuple로 간단하게 사용할 수도 있을 것 같습니다.