Tuple
1.定义
<!--将多个独立的值组合成一个值,变量的容器-->
<!--元祖字面量: 一个值和一个可选名称-->
(x: 1 , y: 2) (1 , 2)
<!--元祖类型: 一个类型和一个可选名称-->
(int , int) (int x , int y)
2.度
泛型度 ^1代表一个参数
(int , long)度2, ("a","b","c")度3。
3.ValueTuple
struct ValueTuple<T1……T8>
//前面七个元素和字面量值进行对应,然后把最后一个元祖作为嵌套的元祖类型用于表示剩余元素
ValueTuple<int, int, int, int, int, int, int, int>
ValueTuple<int, int, int, int, int, int, int, ValueTuple<int>>
4.使用
-
方法
static (int min, int max) MinMax(IEnumerable<int> source) { using (var iterator = source.GetEnumerator()) { if (!iterator.MoveNext()) throw new InvalidOperationException(); // int min = iterator.Current; int max = iterator.Current; while (iterator.MoveNext()) { min = Min(min, iterator.Current); max = Max(max, iterator.Current); } return (min, max); } } // var result = (min: iterator.Current, max: iterator.Current); while (iterator.MoveNext()) { result.min = Min(result.min, iterator.Current); result.max = Max(result.max, iterator.Current); // result = (Min(result.min, iterator.Current), Max(result.max, iterator.Current)); } return result;
-
斐波那契数列
static IEnumerable<int> Fibonacci() { int current = 0; int next = 1; while (true) { yield return current; int oldCurrent = current; current = next; next = oldCurrent + next; } } // var pair = (current: 0, next: 1); while (true) { yield return pair.current; pair = (pair.next, pair.current + pair.next); }
-
constructor
public Person(string name, char sex, int age) => (Name, Sex, Age) = (name, sex, age);
-
表达式
// 一 var tuple = (x: 10, 20); || (int x, int) tuple = (x: 10, 20); // 二 var arr = new[] { ("a", 97) }; || (String, int)[] arr1 = { ("a", 97) }; // 三 String[] input = { "a", "b" }; var query = input.Select(x => (x, x.Length)); IEnumerable<(String, int)> query = input.Select<String, (String, int)>(x => (x, x.Length)); // 四: 下转型 (int, Object) tuple = ((int)1.1, "text"); // 五 (String txt, Func<int, int> func) = (null, x => x * 2); // 六: 变量交换 (x , y) = (y , x);
-
错误
(20,null) //<编译错误>null字面量无法转换成一个类型(20.(String)null) (Item2: 10, 20) //<编译错误>具有二义性|迷惑性,Item1、Item2、Item3…… (int x, int y) tuple = (x: 30, warning: 40); //<警告>CS8123: 名称与顺序要一致 var (x,String y) = (10, "");//<编译错误>var与显示类型不可以同时存在 (byte, Object) tuple = (300, "text"); //<编译错误>CS0029: 300超出了byte的最大值
5. _
不关心变量结果,也根本不需要这个变量,直接丢弃它。使用后不会为当前作用域引用任何新类型
static void Methods(String txt) {
if (txt==null)
throw new ArgumentNullException();
txt.ToString();
//-----------------------------------------------------------------------
_ = txt?.ToString() ?? throw new ArgumentNullException();
}
// 单件模式
public static Person CreateInstance() => _ = person ?? new Person();
6.分解
将一个组合的值分解成多个变量
-
元祖
(int x, int y) = tuple; //------------------------------------------- int x = tuple.Item1; int y = tuple.Item2;
-
非元祖
public void Deconstruct(out String name, out Char sex, out Int32 age) => (name, sex, age) = (Name, Sex, Age); // 1、返回值void,out不能低于2个 // 2、实例方法不可以为泛型,无法推断出类型。扩展方法可以为泛型 // 3、重载与个数无关,编译错误 (String name, Char sex, Int32 age) = new Person("小春", '女', 23);
-
index & range
// index为整形数,不能为负值 // range是一对index组合,代表起始值与终止值 int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int[] copy = arr[4..]; //5, 6, 7, 8, 9 开始下标至结尾 int[] copy = arr[1..3]; //2, 3 [开始下标..结束下标-1] int copy = arr[^2]; //8 倒数第N