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 }
一部のシナリオでは、複数の戻り値を返すメソッドが必要です。Microsoft は、複数のパラメーターを返すことができる Tuple ジェネリック クラスを導入しました。 Item1;Item2,Item3 という順番で名前を付けます。これで問題は部分的に解決されますが、強迫性障害のあるプログラマにとって、Item1、2、3 という名前は単純に耐えられません。そのため、C#7 では、この問題を解決するために、新しいジェネリック型 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 は使用していないようです。コンパイルされたアセンブリを開いて見てみましょう。
fullName.First; コンパイル後も
fullName.Item1
違いは、GetFullName メソッドでは、コンパイラーが簡略化された構文を ValueTuple<string
,string, string> に変換し、新しい属性 (TupleElementNamesAttribute ) を追加して、非常に直感的で分かりやすい「First」「Middle」「Last」をメタデータとして定義しました(ローカルでのみ使用される場合、そのようなメタデータは追加されません)。 TupleElementNamesAttribute ValueTuple と同様に、System.ValueTuple の別の dll にあります。 3. 例
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 }
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 }
(
var begin,
var
)」 2017 -1-1"), DateTime.Parse("2017-12-31")); この行の安っぽい結果は非常に悪いように見えます (上記の行 6 ~ 10 は赤い部分です) )、コンパイルの最適化が不十分であることが問題である可能性があります(リリースコンパイルでも同様です)。 4. 概要 新しい構文形式は確かにはるかに直感的でフレンドリーですが、本質は依然としてジェネリック型の助けを借りて実装されており、コンパイラーも新しい構文形式をサポートする必要があります。
)。
以上がC#タプル (タプル)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。