一探即将到来的 C# 10( 二 )

Natural Delegate Types
lambda 现在会自动创建自然委托类型 。
可以用 var 来创建委托了:
var f = () => 1; // Func<int>var g = string (int x, string y) => $"{y}{x}"; // Func<int, string, string>var g = "test".GetHashCode; // Func<int>调用 lambdas
得益于上述改进 , 创建的类型明确的 lambda 可以直接调用了 。
var zero = ((int x) => x)(0); // 0Caller Expression Attribute(80%)
现在 , CallerArgumentExpression 这个 attribute 终于有用了 。借助这个 attribute , 编译器会自动填充调用参数的表达式字符串 , 例如:
void Foo(int value, [CallerArgumentExpression("value")] string? expression = null){Console.WriteLine(expression + " " + value);}当你这样调用时:
Foo(4 + 5);会输出 4 + 5 = 9 。这对测试极其有用 , 因为你可以输出 assert 的原表达式了:
static void Assert(bool value, [CallerArgumentExpression("value")] string? expr = null){if (!value) throw new AssertFailureException(expr);}default 支持解构(100%)
default 现在支持解构了 , 因此可以给 tuples 直接赋值 。
(int a, int b, int c) = default; // (0, 0, 0)List Patterns(100%)
Pattern Matching 的最后一块版图:list patterns , 终于补齐了 。
void Foo(List<int> list){switch (list){case [4]:Console.WriteLine("长度为 4");break;case { 1, 2, 3 }:Console.WriteLine("元素是 1, 2, 3");break;case { 1, 2, .., var x, 5 }:Console.WriteLine($"前两个元素是 1, 2 , 最后一个元素是 5 , 倒数第二个元素是 {x}");break;default:Console.WriteLine("其他");}}同样的 , 该 pattern 也是 recursive 的 , 因此你可以嵌套其他 patterns 。
除了上述 switch statements 的用法 , 在 if 以及 switch expressions 等地方也同样可用 , 例如:
void Foo(List<int> list){var result = list switch{[4] => ...,{ 1, 2, 3 } => ...,{ 1, 2, .., var x, 5 } => ...,_ => ...};}Abstract Static Member in Interfaces(100%)
C# 10 中 , 接口可以声明抽象静态成员了 , .NET 的类型系统正式具备 virtual static dispatch 能力 。
例如 , 你想定义一个可加而且有零的接口 IMonoid:
interface IMonoid<T> where T : IMonoid<T>{abstract static T Zero { get; }abstract static T operator+(T l, T r);}然后可以对其进行实现 , 例如这里的 MyInt:
public class MyInt : IMonoid<MyInt>{public MyInt(int val) { Value = https://www.isolves.com/it/cxkf/yy/C/2021-06-07/val; }public static MyInt Zero { get; } = new MyInt(0);public static MyInt operator+(MyInt l, MyInt r) => new MyInt(l.Value + r.Value);public int Value { get; }}然后就能写出一个方法对 IMoniod<T> 进行求和了 , 这里为了方便写成扩展方法:
public static class IMonoidExtensions{public static T Sum<T>(this IEnumerable<T> t) where T : IMonoid<T>{var result = T.Zero;foreach (var i in t) result += i;return result;}}最后调用:
List<MyInt> list = new() { new(1), new(2), new(3) };Console.WriteLine(list.Sum().Value); // 6这个特性同样也会对 .NET BCL 做出改进 , 会新增诸如 IAddable<T>、INumeric<T> 的接口 , 并为适用的已有类型实现 。
总结以上就是在 C# 10 的大部分新特性介绍了 , 虽然不保证最终效果和本文效果一致 , 但是也能看到一个大概的方向 。
从 interface 的改进上我们可以看到一个好的预兆:.NET 终于开始动类型系统了 。2008 年至今几乎没有变过的 CTS 显然逐渐不能适应语言发展的需要 , 而 .NET 团队也明确给出了信息表明要在 C# 11 前后对类型系统集中进行改进 , 现在只是一个开始 , 相信不久之后也将能看到 traits、union types、bottom types 和 HKT 等的实装 。

https://mp.weixin.qq.com/s/3kNHgsg4Jth5BRLs1D-92w




推荐阅读