본문 바로가기
TIL (Today I Learned)/C#

[C#] Tuples, ValueTuples

by 둥굴프 2024. 4. 24.
여러 데이터 요소를 그룹화하는 Tuple 타입이 참조 타입이라는 사실을 아시나요?

 

튜플은 여러 데이터 요소를 그룹화하는 유형이다.

나는 튜플을 주로 두 개 이상의 데이터를 반환하는 메서드를 작성할 때 반환값으로 사용했다.

 

그러면 튜플을 선언할 때 주로 사용하는 ( item1, item2 )와 new Tuple<type1, type2>(item1, item2)는 똑같은 튜플일까?

var tuple = new Tuple<string, int>("Tuple", 1);
var tuple2 = ("Tuple", 1);
Console.WriteLine($"tuple type: {tuple.GetType()}");    // 1
Console.WriteLine($"tuple2 type: {tuple2.GetType()}");  // 2
Console.ReadKey();

혹시 아시나요?

 

 

정답은 서로 다른 튜플이다.

 

.... 헉!

tuple type: System.Tuple`2[System.String,System.Int32]
tuple2 type: System.ValueTuple`2[System.String,System.Int32]

1번은 Tuple 타입이고, 2번은 ValueTuple 타입이다.

 

다음에서도 서로 다른 타입이라는 사실을 확인할 수 있다.

C# tuples, which are backed by System.ValueTuple types, are different from tuples that are represented by System.Tuple types.

https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/value-tuples#tuples-vs-systemtuple

 

Tuple의 특징은 다음과 같다.

1. 참조 타입

2. Tuple.Create("Tuple", 1)

3. item1, item2 properties

4. 값을 변경할 수 없다.

5. 최대 8개의 요소 제한이 있다.

 

ValueTuple의 특징은 다음과 같다.

1. 값 타입

2. ("Tuple", 1)

3. item1, item2 properties + 필드명 : (Name: "Tuple", Id: 1)과 같이 선언하면, 해당 필드명으로 접근할 수 있다.

var tuple2 = (Name:"Tuple", Id:1);
Console.WriteLine($"tuple2 Name: {tuple2.Name}{Environment.NewLine}tuple2 Id: {tuple2.Id}");
Console.ReadKey();

 

tuple2 Name: Tuple
tuple2 Id: 1

4. 값을 변경할 수 있다.

5. 8개 이상의 요소로 선언될 수 있다.

 

 

일반적으로 튜플의 생명주기는 짧은 편이다.

*대게 인자로 받거나, 반환값으로 사용하기 때문에 짧다고 표현했다. 목적에 따라 짧지 않을 수 있다.

https://www.reddit.com/r/csharp/comments/rdomyu/whenwhy_to_use_tuples/

https://stackoverflow.com/questions/2745426/practical-example-where-tuple-can-be-used-in-net-4-0

 

 

그렇기 때문에, 메모리 관리가 더 편한 값 타입인 ValueTuple을 사용하는 것이 일반적인 상황에서는 효율적일 것이라고 상상한다.

 

 

그런데 하나 궁금한 게 생긴다.

참조 타입인 Tuple은 왜 Immutable 하고, 값 타입인 ValueTuple은 Mutable 할까?

내부 구조를 보면 쉽게 알 수 있다.

Tuple에서는 readonly로 Immutable 하게 선언되어 있고, ValueTuple은 public으로 접근 및 수정가능하도록 선언되어 있다.

참조타입인 Tuple은 class이며 값 타입인 ValueTuple은 struct인 것을 확인할 수 있다.

private readonly T2 m_Item2;
public T2 Item2;

 

 

 

 

tuple은 무조건 Immutable 할 것이라고 생각했는데, 아니란 것을 알 수 있었다.

'TIL (Today I Learned) > C#' 카테고리의 다른 글

[C#] Reflection, Attributes, Metadata  (0) 2024.04.22
[C#] using, IDisposable  (1) 2024.04.18

댓글