티스토리 뷰

목차

    반응형

    C# Tuple 튜플의 개념(클래스)과 사용 예제 7개 (List, var, string 응용)


    C# 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


    C# Tuple 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


    C# 튜플, 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.

    C# 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


    C# 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


    C# 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


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


    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

    C# Tuple 튜플의 개념(클래스)과 사용 예제 7개 (List, var, string 응용)

    반응형