GetSum(IEnumerable<object> values) 2 { 3 var sum = 0; ; (var item in values) 7 { 8 switch (item) 9 { : ; sval: sum += sval; 14 break; ival: 16 sum += ival; 17 break; str when sum += result; 20 break; 21 case IEnumerable<object> subList when subList.Any(): 22 sum += GetSum(subList); 23 break; 24 default: InvalidOperationException(); 26 } 27 } sum; 30 }
使用方法:
1 switch (item) 2 { 3 case type variable1: ; 6 case type variable2 when predicate: ; 9 default: ; 12 }
原理解析:此 switch 非彼 switch,编译后你会发现扩展的 switch 就是 as 、if 、goto 语句的组合体。同 is expressions 一样,以前我们也能实
现只是写法比较繁琐并且可读性不强。
总结:模式匹配语法是想让我们在简单的情况下实现类似与多态一样的动态调用,即在运行时确定成员类型和调用具体的实现。
到了加强,它不仅可以获取值类型的引用而且还可以获取某个变量(引用类型)的局部引用。如:
GetLocalRef(int[,] arr, Func<int, bool> func) 2 { 3 for (int i = 0; i < arr.GetLength(0); i++) 4 { 5 for (int j = 0; j < arr.GetLength(1); j++) 6 { 7 if (func(arr[i, j])) 8 { arr[i, j]; 10 } 11 } 12 } InvalidOperationException(); 15 }
Call:
1 int[,] arr = { { 10, 15 }, { 20, 25 } }; num = ref GetLocalRef(arr, c => c == 20); 3 num = 600; 4 5 Console.WriteLine(arr[1, 0]);
Print results:
使用方法:
1. 方法的返回值必须是引用返回:
a) 声明方法签名时必须在返回类型前加上 ref 修饰。
b) 在每个 return 关键字后也要加上 ref 修饰,以表明是返回引用。
2. 分配引用(即赋值),必须在声明局部变量前加上 ref 修饰,以及在方法返回引用前加上 ref 修饰。
注:C# 开发的是托管代码,所以一般不希望程序员去操作指针。并由上述可知在使用过程中需要大量的使用 ref 来标明这是引用变量(编译后其
实没那么多),当然这也是为了提高代码的可读性。
总结:虽然 C# 7 中提供了局部引用和引用返回,但为了防止滥用所以也有诸多约束,如:
1. 你不能将一个值分配给 ref 变量,如:
num = 10; // error:无法使用值初始化按引用变量
2. 你不能返回一个生存期不超过方法作用域的变量引用,如:
GetLocalRef(int num) => ref num; // error: 无法按引用返回参数,因为它不是 ref 或 out 参数
3. ref 不能修饰 “属性” 和 “索引器”。