C#Tuples(元组)
Mar 12, 2017 pm 03:47 PM1. 老版本代码
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 }
在有些场景下,我们需要一个方法返回一个以上的返回值,微软在.NET 4中引入了Tuple这个泛型类,可以允许我们返回多个参数,每个参数按照顺序被命名为 Item1;Item2,Item3 ,算是部分的解决了我们的问题,但是对于强迫症程序员来说,Item1,2,3的命名简直是不能忍的,,,so,在C#7中,引入了一个新的泛型类型ValueTuple<T>来解决这个问题,这个类型位于一个单独的dll(System.ValueTuple)中,可以通过nuget来引入到你当前的项目中(http://www.php.cn/)。
2. 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 }
看出来差别了吗?我们终于可以用更直观的名字来替换掉该死的"Item1,2,3"了,看起来很棒吧。但是貌似我们并没有用到上面我提到的System.ValueTuple,我们翻开编译后的程序集看看:
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 }
不看不知道,一看吓一跳,原来我们的 fullName.First; 编译后居然还是 fullName.Item1 ,真是日了狗了。。。
不同之处在于GetFullName这个方法,编译器把我们简化的语法形式翻译成了 ValueTuple<string, string, string> ,还给加了一个新的Attribute(TupleElementNamesAttribute),然后把我们自定义的非常直观友好的“First”,"Middle","Last"当作元数据给存起来了(如果只是局部使用,则不会添加这样的元数据)。TupleElementNamesAttribute和ValueTuple一样,位于System.ValueTuple的单独dll中。
3. Example
1 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 }
look一下编译后的代码:
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 }
注意 (var begin, var end) = (DateTime.Parse("2017-1-1"), DateTime.Parse("2017-12-31")); 这一行的便宜结果,看起来很是糟糕(上述6-10行红色部分),可能还是编译优化不足的问题吧(release编译也是如此)。
4. 总结
新的语法形式确实直观友好了好多,but,本质依然是借助泛型类型来实现的,同时也需要编译器对新语法形式的支持。
了解了本质是什么东西之后,以后在项目中环境允许的话,就放心大胆的使用吧(类型ValueTuple可以出现的地方,(first,last)这种新语法形式均可以)。
Atas ialah kandungan terperinci C#Tuples(元组). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Artikel Panas

Alat panas Tag

Artikel Panas

Tag artikel panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)
