Od C# 7 (.NET 4.7) dostepna jest nowa klasa - ValueTuple. Jest ona alternatywą dla klasy Tuple, o której pisałam tutaj.
Podstawowe różnice między ValueTuple a Tuple:
- ValueTuple to value type, zaś Tuple to reference type (więcej o różnicy tutaj)
- ValueTuple można stworzyć za pomocą prostej składni z nawiasami
- ValueTuple może zawierać w sobie więcej niż 8 elementów
- ValueTuple może mieć nazwane elementy
- ValueTuple może zostać zdekonstruowany do pojedynczych zmiennych
ValueTuple można stworzyć na następujące sposoby:
Wprost sprecyzować typ:
ValueTuple<int, string,string> person = (1, "Dziki", "Bill");
Możemy darować sobie napisanie "ValueTuple":
(int, string,string) person = (1, "Dziki", "Bill");
Albo w ogóle pozwolić kompilatorowi samemu wywnioskować typ na podstawie parametrów:
var person = (1, "Dziki", "Bill");
Uwaga. Chcąc utworzyć ValueTuple z tylko jednym elementem (ciężko mi wyobrazić sobie po co, ale do odważnych świat należy) musimy zastosować składnię:
ValueTuple<int> number = new ValueTuple<int>(2);
Napisanie...
var number = (1);
...utworzy inta, a nie ValueTuple.
ValueTuple może zawierać więcej niż 8 elementów:
var data = (1, 2, 3, 4, 5, 6, 7, 8, 9);
Wciąż do elementów można dostać się poprzez pola Item1, Item2 itd:
var data = (1, 2, 3, 4, 5, 6, 7, 8, 9); var first = data.Item1;
Na szczęście w ValueTuple możemy nazywać poszczególne elementy:
(int Id, string FirstName, string LastName) person = (1, "Dziki", "Bill")
Możemy je nazwać także po prawej stronie przypisania:
var person = (Id: 1, FirstName: "Dziki", LastName: "Bill")
Wtedy użycie takiego obiektu zaczyna wyglądać trochę bardziej sensownie, niż miało to miejsce przy Tuple:
var person = (Id: 1, FirstName: "Dziki", LastName: "Bill"); var firstName = person.FirstName;
Przekazując ValueTuple przez parametr, musimy pamiętać o specyficznej składni z nawiasami:
void PrintPersonTuple((int, string, string) person) { }
Podobnej składni użyjemy zwracając ValueTuple z metody:
(int, string, string) GetPerson() { return (Id:1, FirstName: "Dziki", LastName: "Bill"); }
Przyjrzyjmy się jeszcze dekonstrukcji ValueTuple. Jest to mechanizm pozwalający nam wydobyć poszczególne elementy z ValueTuple i przypisać je do zmiennych:
(int personId, string personName, string personLastName) = GetPerson(); (int, string, string) GetPerson() { return (Id:1, FirstName: "Dziki", LastName: "Bill"); }
Jeśli nie chcemy użyć któregoś z pól ValueTuple, możemy użyć następującej składni:
(int personId, _, string personLastName) = GetPerson(); (int, string, string) GetPerson() { return (Id:1, FirstName: "Dziki", LastName: "Bill"); }
Na koniec nasuwa się takie samo pytanie, jakie pojawiło się przy zwykłych Tuple: kiedy należy ich używać? Moim zdaniem mimo że ValueTuple rozwiązały część problemów, jakie dotyczyły Tuple, wciąż w większości przypadków lepiej użyć klasy lub struktury do agregowania różnych informacji w spójną całość. Więcej o zasadności użycia Tuple można znaleźć pod koniec tego posta.
Komentarze
Prześlij komentarz