Klasa Tuple

W .NET 4.0 wprowadzoną klasę Tuple służącą do owijania kilku wartości w jeden obiekt. Tuple to nic innego jak obiekt zawierający w sobie jakieś dane w postaci właściwości. Do dyspozycji jest 8 statycznych  metod służących do stworzenia Tuple:

  • Create(T1)
  • Create(T1,T2)
  • Create(T1,T2,T3)
  • Create(T1,T2,T3,T4)
  • Create(T1,T2,T3,T4,T5)
  • Create(T1,T2,T3,T4,T5,T6)
  • Create(T1,T2,T3,T4,T5,T6,T7)
  • Create(T1,T2,T3,T4,T5,T6,T7,T8)

Ponadto istnieje możliwość stworzenia tuple za pomocą jednego z konstruktorów:

  • Tuple<T1>
  • Tuple<T1,T2>
  • Tuple<T1,T2,T3>
  • Tuple<T1,T2,T3,T4>
  • Tuple<T1,T2,T3,T4,T5>
  • Tuple<T1,T2,T3,T4,T5,T6>
  • Tuple<T1,T2,T3,T4,T5,T6,T7>
  • Tuple<T1,T2,T3,T4,T5,T6,T7,TRest>

Załóżmy, że chcemy stworzyć obiekt zawierający dwa pola: jedno string drugie int:

Tuple<string, int> tuple = Tuple.Create("Piotr", 26);
string firstName = tuple.Item1;
int age = tuple.Item2;

Należy zaznaczyć, że Tuple jest obiektem immutable i zmiana pól po utworzeniu jest już niemożliwa:

Tuple<string, int> tuple = Tuple.Create("Piotr", 26);
tuple.Item1 = "Piotr"; // niemozliwe - readonly
tuple.Item2 = 30; // niemozliwe - readonly

Oczywiście nic nie szkodzi na przeszkodzie aby stworzyć zagnieżdżone obiekty:

var tuple = Tuple.Create(Tuple.Create("Piotr", "Zielinski"), 26);
string firstName = tuple.Item1.Item1;
string lastName = tuple.Item1.Item2;
int age = tuple.Item2;

Korzystanie z metody statycznej Create myślę, że jest już jasne. Jak jednak wspomniałem, istnieje możliwość tworzenia tuple za pomocą konstruktorów:

var tuple = new Tuple<string, string>("Piotr", "Zielinski");
string firstName = tuple.Item1;
string lastName = tuple.Item2;

Najbardziej interesującym konstruktorem jest “Tuple<T1,T2,T3,T4,T5,T6,T7,TRest>”, który pozwala na zdefiniowanie więcej niż 8 wartości:

var tuple = new Tuple<int, int, int, int, int, int, int, Tuple<int, int>>(1, 2, 3, 4, 5, 6, 7,
                                                                                      new Tuple<int, int>(8, 9));
int item1 = tuple.Item1;
int item7 = tuple.Rest.Item1;
int item8 = tuple.Rest.Item2; 

Tuple to nie kolekcja – nie ma enumeratora. Kiedy warto tego używać? Moim zdaniem nigdy! Część programistów używa jednak tuple w wewnętrznych klasa np. przekazując parametry do wątku. Wszyscy natomiast odradzają eksponowania Tuple jako publiczna właściwość czy wartość zwracana przez funkcje. Osobiście nie używam tego tworu nawet w wewnętrznych klasach jako tymczasowe zmienne. Preferuje używać własne klasy, które zawierają właściwości z nazwami odzwierciedlającymi prawdziwe przeznaczenie. Wyjątkiem są aplikacje tymczasowe np. na szybko tworzone prototypy – uważam, że prototyp przede wszystkim musi zostać zaimplementowany szybko bo od niego zależy wiele ważnych decyzji.

8 thoughts on “Klasa Tuple”

  1. przeczytałem w rss-ie “Klapsa w tuple” i się zastanawiałem co to tam znowu Zieliński pisze 😉 A merytorycznie, również nigdy nie używam, nie miałem powodu żeby użyć, nawet na siłę.

  2. Taka ciekawostka: Tuple w pełnym .NET jest Serializable (np. w WCF). Z kolei w Silverlight 4 już nie.

    Po pierwsze wystawienie Tuple w DataContract (WCF) i odebranie go w kliencie (Silverlight) kończy się Exception’em, bo nie da się deserializować takiego obiektu.

    Po drugie stworzyłem w zamian mały DataContract z 3 properties, które chciałem przesyłać.

    Po trzecie odradzam stosowania Tuple, bo nie są czytelne. Zamiast Item1, Item2, Item3 lepiej mieć przecież Id, FirstName, LastName.

  3. To chyba w ramach ‘ufunkcyjniania’ C#.

    Są lambdy, jest LINQ, dodano też krotki. Niestety ten koncept nie pasuje do C# jako takiego.
    Tuple jest pozbawiona swojej podstawowej zalety – zwięzłości i prostoty, oraz, co jeszcze gorsze, nie da się z nim (nią) nic ciekawego zrobić.

    Dziękuję, nie skorzystam na razie.

  4. Tekst dla mnie przydatny – zacząłem czytać kiedyś o krotkach ale nie załapałem o co chodzi – tutaj – wszystko jasne.

  5. Nie używasz może dlatego, że w C# są wyrwane z kontekstu – dla przykłady w Python (nie wiem czy F# też) tuple są immutable ergo raz zapisane wartości pozostają niezmienne – bardzo przydatne jeśli chodzi o konfiguracje i używanie wielu wartości zbiorczo.

  6. Teraz są ValueTuple i osobiście zacząłem używać. Bardzo przydatne. (int Id, string Name) a = (1, “abc” ) ; lub var t = (Some: 123, Text: “Krotka”) ;

Leave a Reply

Your email address will not be published.