Maison >développement back-end >Tutoriel C#.Net >C#Tuples (Tuples)
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var fullName = GetFullName(); 6 7 Console.WriteLine(fullName.Item1);// Item1,2,3不能忍,,, 8 Console.WriteLine(fullName.Item2); 9 Console.WriteLine(fullName.Item3);10 }11 static Tuple<string, string, string> GetFullName() => new Tuple<string, string, string>("first name", "blackheart", "last name");12 }
Dans certains scénarios, nous avons besoin d'une méthode pour renvoyer plus d'une valeur de retour Microsoft l'a introduit dans .NET 4 Tuple. est une classe générique qui nous permet de renvoyer plusieurs paramètres. Chaque paramètre est nommé Item1;Item2,Item3 dans l'ordre. Cela résout partiellement notre problème, mais pour les programmeurs souffrant de trouble obsessionnel-compulsif, le nom de Item1. ,2,3 est tout simplement intolérable,,, donc, en C#7, un nouveau type générique ValueTuple
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var fullName = GetFullName(); 6 7 Console.WriteLine(fullName.First); // 终于可以不是Item1,2,3了,,, 8 Console.WriteLine(fullName.Middle); 9 Console.WriteLine(fullName.Last);10 }11 12 static (string First, string Middle, string Last) GetFullName() => ("first name", "blackheart", "last name");13 }Pouvez-vous voir la différence ? On peut enfin remplacer ce foutu "Item1,2,3" par des noms plus intuitifs, ça a l'air génial. Mais il semble que nous n'ayons pas utilisé le System.ValueTuple que j'ai mentionné ci-dessus. Ouvrons l'assembly compilé et jetons un œil :
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 ValueTuple<string, string, string> fullName = Program.GetFullName(); 6 Console.WriteLine(fullName.Item1); // 原来你还是Item1,2,3,,,FUCK!!! 7 Console.WriteLine(fullName.Item2); 8 Console.WriteLine(fullName.Item3); 9 }10 11 [TupleElementNames(new string[]12 {13 "First",14 "Middle",15 "Last"16 })]17 private static ValueTuple<string, string, string> GetFullName()18 {19 return new ValueTuple<string, string, string>("first name", "blackheart", "last name");20 }21 }Je ne sais pas si. vous ne savez pas. J'ai été choqué quand je l'ai vu. Il s'est avéré que notre
fullName.First; s'est avéré être fullName.Item1 après la compilation. . . La différence entre
est que dans la méthodeGetFullName, le compilateur traduit notre syntaxe simplifiée en ValueTuple<string, string, string>, et a également ajouté un nouvel attribut (TupleElementNamesAttribute), puis nous avons défini les très intuitifs et conviviaux "Premier", "Milieu", "Last" "Stockés comme métadonnées (Si elles sont utilisées uniquement localement, ces métadonnées ne seront pas ajoutées). TupleElementNamesAttribute est identique à ValueTuple et se trouve dans une DLL distincte de System.ValueTuple.
3. Exemple1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var range = (first: 1, end: 10); 6 //也可以这样写,效果是一样的,编译后都是没有了first,end的痕迹,,,first和end只是语法层面的障眼法 7 //(int first, int last) range = (1, 10); 8 Console.WriteLine(range.first); 9 Console.WriteLine(range.end);10 11 //可以使用var,这种无显示声明一个变量的方式会编译出多余的代码,慎用,不知是不是还未优化好。12 (var begin, var end) = (DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31"));13 Console.WriteLine(begin);14 Console.WriteLine(end);15 16 //begin,end可以被覆盖重命名为startDate和endDate,但是会有一个编译警告,提示名字被忽略掉了。17 //warning CS8123: The tuple element name 'begin' is ignored because a different name is specified by the target type '(DateTime startDate, DateTime endDate)'18 //warning CS8123: The tuple element name 'end' is ignored because a different name is specified by the target type '(DateTime startDate, DateTime endDate)‘19 (DateTime startDate, DateTime endDate) timeSpan = (begin: DateTime.Parse("2017-1-1"), end: DateTime.Parse("2017-12-31"));20 Console.WriteLine(timeSpan.startDate);21 Console.WriteLine(timeSpan.endDate);22 }23 }Regardez le code compilé :
1 private static void Main(string[] args) 2 { 3 ValueTuple<int, int> range = new ValueTuple<int, int>(1, 10); 4 Console.WriteLine(range.Item1); 5 Console.WriteLine(range.Item2); 6 ValueTuple<DateTime, DateTime> expr_3C = new ValueTuple<DateTime, DateTime>(DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31")); 7 DateTime item = expr_3C.Item1; 8 DateTime item2 = expr_3C.Item2; 9 DateTime begin = item; 10 DateTime end = item2;11 Console.WriteLine(begin);12 Console.WriteLine(end);13 ValueTuple<DateTime, DateTime> timeSpan = new ValueTuple<DateTime, DateTime>(DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31"));14 Console.WriteLine(timeSpan.Item1);15 Console.WriteLine(timeSpan.Item2);16 }Remarque
(var début, var fin) = (DateTime.Parse(" 2017 -1-1"), DateTime.Parse("31/12/2017")); Le résultat bon marché de cette ligne semble très mauvais (la partie rouge des lignes 6 à 10 ci-dessus). Il peut s'agir d'un problème d'optimisation insuffisante de la compilation (il en va de même pour la compilation des versions).
4.Où le type ValueTuple peut apparaître, (premier, dernier) ce nouveau Any la forme grammaticale peut être ).
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!