Klasa (immutable) Tuple istniała aż od .NET Framework 4.0. W C# 7.0 mamy jednak wsparcie dla tuple od strony języka. Jednym z problemów klasy Tuple było, że każda właściwość nazywała się kolejno Item1, Item2 itp.
Przykład:
class Program { private static void Main(string[] args) { var tuple = GetFirstAndLastName(); Console.WriteLine(tuple.Item1); Console.WriteLine(tuple.Item2); } private static Tuple<string,string> GetFirstAndLastName() { var tuple = new Tuple<string, string>("Piotr", "Zielinski"); return tuple; } }
W wersji 7.0, powyższy kod możemy przepisać do:
class Program { private static void Main(string[] args) { var tuple = GetFirstAndLastName(); Console.WriteLine(tuple.firstName); Console.WriteLine(tuple.lastName); } private static (string firstName, string lastName) GetFirstAndLastName() { var fullName = (firstName: "Piotr", lastName: "Zielinski"); return fullName; } }
Składnia dużo czytelniejsza ponieważ nie operujemy już na Item1 i Item2. Zobaczmy co się kryje za tym nowym “Tuple” po dekompilacji:
internal class Program { // Method .ctor with token 06000003 public Program() { base.\u002Ector(); } // Method Main with token 06000001 private static void Main(/*Parameter with token 08000001*/string[] args) { ValueTuple<string, string> firstAndLastName = Program.GetFirstAndLastName(); Console.WriteLine(firstAndLastName.Item1); Console.WriteLine(firstAndLastName.Item2); } // Method GetFirstAndLastName with token 06000002 private static ValueTuple<string, string> GetFirstAndLastName() { return new ValueTuple<string, string>("Piotr", "Zielinski"); } }
Całość opiera się na zwykłej strukturze ValueTuple<string, string>. Wygląda to bardzo analogicznie do starego Tuple<T1,T2>. Zaglądając do źródeł ValueTuple, przekonamy się, że klasa jest immutable i przeładowuje metody typu Equals oraz GetHashCode. Oznacza to, że typ doskonale nadaję się jako klucz do słowników.
Powyższy kod można przetestować używając Visual Studio ’15’ preview 3, który jest dostępny tutaj.