C#/자료구조

[C#][자료구조] Tuple 튜플

자가라o 2021. 9. 16. 07:24

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로 간단하게 사용할 수도 있을 것 같습니다.