C# Tuple 튜플의 개념과 사용 예제

C# Tuple 튜플의 개념과 사용 예제


Tuple. 고양이 한 마리가 방 안으로 들어옵니다. 이 고양이의 털은 노랗고, 부드럽습니다. 튜플은 이런 정보를 모두 저장할 수 있는 클래스입니다. 튜플의 인스턴스들은 변경할 수 없는(immutable) 고정 항목을 갖습니다. 그리고 Tuple의 타입은 Class라는 것을 잊지 마세요.


아래 예제에선 3개의 아이템을 갖는 튜플을 선합니다. 그리고, 아이템 1, 2, 3의 속성을 읽습니다. 변경하진 않습니다. (못합니다)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
 
class Program
{
    static void Main()
    {
        // Create three-item tuple.
        Tuple<intstringbool> tuple = new Tuple<intstringbool>(1"cat"true);
 
        // Access tuple properties.
        if (tuple.Item1 == 1)
        {
            Console.WriteLine(tuple.Item1);
        }
 
        if (tuple.Item2 == "dog")
        {
            Console.WriteLine(tuple.Item2);
        }
 
        if (tuple.Item3)
        {
            Console.WriteLine(tuple.Item3);
        }
    }
}
==
Output
1
2
3
4
cs

Item Types. 튜플 내부에 서로 다른 타입들을 선언할 수 있습니다. 예를 들어, double, byte, char 요소들은 이렇게 하나의 튜플로 묶을 수 있습니다. (Tuple<double, byte, char> )


Note: 예를 들어 int value 타입과 string 참조 타입을 함께 사용할 수 있습니다.


4 items. 배열을 보유하는 더 복잡한 튜플도 선언할 수 있으며, 이에 따라 또 다른 메소드로 튜플을 이용합니다.


아래: 이 예제는 튜플이 갖는 4개의 아이템 중 하나는 string 배열, 또 하나는 int 배열입니다.


아래 예제에선 Tuple 생성자를 호출할 때, 배열들을 초기화합니다. 근데 var 키워드를 왜 사용할까요? 문법을 더 예쁘고 짧게 만들어주기 때문입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
 
class Program
{
    static void Main()
    {
        // Create four-item tuple.
           // ... Use var implicit type.
        var tuple = new Tuple<stringstring[], intint[]>(
            "perl",
            new string[] { "java""c#" },
            1,
            new int[] { 23 });
 
        // Pass tuple as argument.
        M(tuple);
    }
 
    static void M(Tuple<stringstring[], intint[]> tuple)
    {
        // Evaluate the tuple's items.
        Console.WriteLine(tuple.Item1);
 
        foreach (string value in tuple.Item2)
        {
            Console.WriteLine(value);
        }
 
        Console.WriteLine(tuple.Item3);
 
        foreach (int value in tuple.Item4)
        {
            Console.WriteLine(value);
        }
    }
}
==
perl
java
c#
1
2
3
cs


Sixtuple. 6개의 파라미터 리스트를 선언하고 초기화하여 사용합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
 
class Program
{
    static void Main()
    {
        var sixtuple =
            new Tuple<intintintstringstringstring>(1,
            12"dot""net""perls");
 
        Console.WriteLine(sixtuple);
    }
}
==
(112, dot, net, perls)
cs


Visual Studio에서, 마우스를 var 키워드 위에 올리면 var는 Represents a 6-tuple, or sextuple.이라는 설명과 함께 타입들을 설명합니다. (역주, 전 2015 사용 중인데 안 됩니다. 보여지는 조건이 따로 있을까요?)


C# 5.0


Note: 튜플의 이름은 대부분 프로그램에서 중요하진 않습니다. 그러나 간단한 아래의 간단한 용어들은 경우에 따라 유용할 수도 있습니다.


Names:

A 2-tuple is called a pair.

A 3-tuple is called a triple.

A 4-tuple is called a quadruple.

A 5-tuple is called a quintuple.

A 6-tuple is called a sextuple.

A 7-tuple is called a septuple.

Larger tuples are called n-tuples.


Tuple.Create. Invoke 메소드로 예제에선 3개의 인자를 사용합니다(string, int, bool). 결과, Create() 함수는 Tuple<string, int, bool> 형태의 클래스를 리턴합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
 
class Program
{
    static void Main()
    {
        // Use Tuple.Create static method.
        var tuple = Tuple.Create("cat"2true);
 
        // Test value of string.
        string value = tuple.Item1;
 
        if (value == "cat")
        {
            Console.WriteLine(true);
        }
 
        // Test Item2 and Item3.
        Console.WriteLine(tuple.Item2 == 10);
        Console.WriteLine(!tuple.Item3);
 
        // Write string representation.
        Console.WriteLine(tuple);
    }
}
==
True
False
False
(cat, 2, True)
cs

Internals. instance를 리턴하는 함수(또는 알고리즘) 중 Tuple.Create() (생성자)보다 더 나은 알고리즘은 없습니다. 그러나, 아래 코드에선 Tuple.Create를 호출하지 않으나, 더 나아 보입니다.


1
2
3
4
public static Tuple<T1> Create<T1>(T1 item1)
{
    return new Tuple<T1>(item1);
}
cs


Class implementation. Tuple은 구조체가 아니라 클래스입니다. managed 힙에 할당되기에 각각의 인스턴스들은 가비지 콜렉터가 관리해야 할 항목으로 추가됩니다.


Note: 아이템1, 아이템2, 아이템n... 속성들은 setter가 없습니다. 우리는 튜플 속성이 메모리에 할당되면 변경할 수 없습니다.


C# tuple


Read-only. 튜플의 생성자를 호출할 땐, 반드시 튜플 내의 모든 값을 초기화해야 합니다. 생성자가 실행되어 메모리에 할당되면 더는 속성을 변경할 수 없습니다. 이 점을 간과하면, 많은 변경 사항이 유발되어 유지 보수 사항이 늘어납니다. 성능 하락에 영향을 미칠 수도 있습니다.


1
2
Property or indexer 'System.Tuple...Item1'
    cannot be assigned to--it is read-only.
cs


Performance. KeyValuePair를 이용해 비교한 결과, 객체를 많이 생성한 경우엔 KeyValuePair, 함수 호출(전달)의 경우엔 Tuple이 더 빠릅니다. Tuple을 인자로 넘길 땐 4바이트씩 복사하지만, KeyValuePair는 구조체 등 더 많은 바이트를 복사합니다.


Sort. 튜플도 정렬이 됩니다. 데이터 캡슐화를 위한 좋은 방법이죠. 그러나 정렬 기능 구현이 어렵고, 비교 기능을 가진 delegate가 필요합니다.


First: 아래 예제에선 List를 생성하고 그 안에 튜플 객체 3개를 추가합니다. 그리고 List의 Sort 함수를 호출합니다.

Here: 람다를 이용하여 함수 인자(a, b)에 대한 결과값을 Item2의 속성으로 전달합니다.


Tip1: a와 b를 뒤집어 사용해도 됩니다. (결과 같음)

Tip2: 튜플을 정렬할 다른 방법도 있죠. LINQ의 쿼리 문법도 좋은 방법입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Collections.Generic;
 
class Program
{
    static void Main()
    {
    List<Tuple<intstring>> list = new List<Tuple<intstring>>();
    list.Add(new Tuple<intstring>(1"cat"));
    list.Add(new Tuple<intstring>(100"apple"));
    list.Add(new Tuple<intstring>(2"zebra"));
 
    // Use Sort method with Comparison delegate.
    // ... Has two parameters; return comparison of Item2 on each.
    list.Sort((a, b) => a.Item2.CompareTo(b.Item2));
 
    foreach (var element in list)
    {
        Console.WriteLine(element);
    }
    }
}
==
(100, apple)
(1, cat)
(2, zebra)
cs


Return multiple values. 오래도록 문제점으로 지적되던 것 중 하나입니다. 함수는 여러 인자를 받을 수는 있지만 리턴값(리턴 타입)은 오직 하나뿐이었죠. 그러나 튜플은 (자료형이 다른) 여러 데이터를 리턴합니다. (같은 기능을 클래스로 구현하는 것보다 합리적)


Note: 튜플의 장점 중 하나는 재사용성입니다. 다른 함수를 이용해 더 자유롭게 사용할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
 
class Program
{
    static Tuple<stringint> NameAndId()
    {
        // This method returns multiple values.
        return new Tuple<stringint>("Gudrun"673);
    }
 
    static void Main(string[] args)
    {
        var result = NameAndId();
        string name = result.Item1;
        int id = result.Item2;
 
        // Display the multiple values returned.
        Console.WriteLine(name);
        Console.WriteLine(id);
    }
}
==
Gudrun
673
cs


A summary. Tuple은 변경 불가 타입(immutable)이며, 여러 타입의 데이터를 저장할 수 있는 유용한 컨테이너입니다.



튜플의 또 다른 예튜플의 또 다른 예

(튜플의 예, 튜플 안에 리스트를 두어 사용)


출처 - https://www.dotnetperls.com/tuple

신고

이 글을 공유하기

댓글(0)

Designed by JB FACTORY