C# 10 新特性——补充篇

Intro

Intro

前面已经写了几篇文章介绍 C# 10 新特性的文章,还有一些小的更新

Constant interpolated strings

在之前的版本中,如果想要使用插值字符串来,则不能声明为一个常量

如果依赖于一个常量的插值字符串就只能声明为一个 static 的变量,比如说下面这个例子:

private const string Name = "Alice";private static readonly string Hello = $"Hello {Name}";

在 C# 10 中我们可以将 Hello 也声明为常量(const),如下:

public string const Name = "Alice";public string const Hello = $"Hello {Name}";

这种常量插值字符串参数只适用于字符串,如果是 int 就不行了,比如说,如果写一段下面这样的代码:

private const int Num = 10;private const string HelloNum = $"Hello {Num}";

这里插值字符串的参数是一个 int 类型,实际编译器会直接报错,报错信息如下:

// Error CS0133 The expression being assigned to 'ConstantInterpolatedStringSample.HelloNum' must be constant

上一篇文章中,我们有提到像 int/DateTime 等这种数据字符串插值是会依赖当前的一个 CultureInfo,所以作为插值字符串的时候不是一个编译时就确定的一个值,不能被认为是常量

这个特性的插值参数必须是字符串常量。

Extended property patterns

C# 10 针对模式匹配有一点小优化,针对嵌套的属性模式写法做了一些简化,如:

if (e is MethodCallExpression { Method: { Name: "MethodName" } })

C# 10 新写法:

if (e is MethodCallExpression { Method.Name: "MethodName" })

一个完整的简单小例子如下:

record TestModelA(TestModelB B, string Name);record TestModelB(TestModelC C, string Name);record TestModelC(string Name);var a = new TestModelA(new TestModelB(new TestModelC("C"), "B"), "A");if (a is { B.C.Name.Length: > 0 }){    Console.WriteLine(a.B.C.Name);}

Record types can seal ToString

在 C# 10 中我们可以把 record 类型的 ToString() 方法标记为 sealed,这样继承于它的子类就不能再重写这个方法了,可以用来保护 ToString() 输出的格式,保证输出的格式是一致的,使用起也很简单,直接在 ToString 方法中声明 sealed 即可,示例如下:

record Person(string Name, int Age){    public sealed override string ToString()    {        return Name;    }}

这样如果继承于它的 record 想要重写 ToString 方法的时候就会报错

C# 10 新特性——补充篇

前面我们提到过 C# 10 中增加了 record struct,它可以使用这个特性吗?答案是不可以,这一特性仅针对于 record class,在 record struct 中使用会得到一个类似下面的错误

C# 10 新特性——补充篇

Assignment and declaration in same deconstruction

在之前的版本中,我们如果想要使用 tuple 返回值,必须要同时初始化,如下:

private static (int month, int day) GetDate(){    var today = DateTime.Today;    return (today.Month, today.Day);}(var month, var day) = GetDate();Console.WriteLine($"Month: {month}, day: {day}");

我们必须要同时声明 month/day,在 C# 10 中我们既可以使用已有变量又可以声明新的变量,可以结合在一起使用,如下:

(var month, var day) = GetDate();Console.WriteLine($"Month: {month}, day: {day}");(month, var day2) = GetDate();Console.WriteLine($"Month: {month}, day: {day2}");(month, day) = GetDate();Console.WriteLine($"Month: {month}, day: {day}");

Improved definite assignment

C# 10 中编译器会做更多的推断从而大大方便我们的使用,之前介绍的 Lamdba 的一些优化都是由编译器做的推断,针对于初始化赋值的 null 检查也有一些优化,下面是微软给出的一个示例,在之前的版本中会有警告,但是在 C# 10 之后就没有警告了

string representation = "N/A";if ((c != null && c.GetDependentValue(out object obj)) == true){   representation = obj.ToString(); // undesired error}// Or, using ?.if (c?.GetDependentValue(out object obj) == true){   representation = obj.ToString(); // undesired error}// Or, using ??if (c?.GetDependentValue(out object obj) ?? false){   representation = obj.ToString(); // undesired error}

Allow AsyncMethodBuilder attribute on methods

从 C# 10 开始我们可以在异步方法上设置 AsyncMethodBuild 来自定义要处理异步任务的方式,这有对于要实现性能更好的异步方法处理方式的用户会更加的方便

比如这样一个异步方法:

public async ValueTask<T> ExampleAsync() { ... }

实际编译器会生成这样的代码:

[AsyncStateMachine(typeof(<ExampleAsync>d__29))][CompilerGenerated]static ValueTask<int> ExampleAsync(){    <ExampleAsync>d__29 stateMachine;    stateMachine.<>t__builder = AsyncValueTaskMethodBuilder<int>.Create();    stateMachine.<>1__state = -1;    stateMachine.<>t__builder.Start(ref stateMachine);    return stateMachine.<>t__builder.Task;}

使用这种方式,我们可以控制异步方法的处理

[AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))] // new usage, referring to some custom builder typestatic async ValueTask<int> ExampleAsync() { ... }

这样实际生成的代码类似下面这样

[AsyncStateMachine(typeof(<ExampleAsync>d__29))][CompilerGenerated][AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))] // retained but not necessary anymorestatic ValueTask<int> ExampleAsync(){    <ExampleAsync>d__29 stateMachine;    stateMachine.<>t__builder = PoolingAsyncValueTaskMethodBuilder<int>.Create(); // <>t__builder now a different type    stateMachine.<>1__state = -1;    stateMachine.<>t__builder.Start(ref stateMachine);    return stateMachine.<>t__builder.Task;}

更多细节可以参考:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/async-method-builders

Generic Attribute

Generic Attribute 目前还不算是 C# 10 新特性中的一部分,但是已经可以使用了,需要声明 LangVersion 为 preview,否则会看到类似下面的一个错误

C# 10 新特性——补充篇

Generic Attribute Requires preview LangVersion

因为可以用了,而且想在我的项目里使用,所以想尝试一下,但是就目前来说,还不能满足我的需要,简单看一下好了

我们可以这样用

[ExcelConfiguration<TestModel>]public class TestModel{    public int Id { get; set; }    public string Title { get; set; } = string.Empty;}[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]public class ExcelConfigurationAttribute<T> : Attribute{    public string DefaultFileName { get; set; } = "unnamed-file.xlsx";    public Func<T, bool> DataValiadator { get; set; } = _ => true;}

但是如果想在声明 Attribute 的地方指定泛型委托会报错,错误信息如下:

C# 10 新特性——补充篇

Generic Lambda Error

对于预览版特性,如果不是特别需要建议还是不要轻易在生产代码里用,以后被砍了就尴尬了

More

原来有很多原本计划在 C#10 的特性被推到了 C# 11中,比如 filed 关键词、required成员针对集合的模式匹配等,但总体来说还是有很多不错的新特性了,还没用 C# 10 的小伙伴们可以用起来了~~

C# 10 新特性解析的系列文章到此就结束了,如果有错误的地方欢迎指出,万分感谢

C# 10 新特性的示例代码可以从 Github 上获取:https://github.com/WeihanLi/SamplesInPractice/tree/master/CSharp10Sample

更多特性介绍可以参考微软的文档,可以参考文末的参考链接

References

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10

  • https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/constant_interpolated_strings
  • https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/extended-property-patterns
  • https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/improved-definite-assignment
  • https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/async-method-builders

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/126207.html

(0)

相关推荐

  • 广州车展前瞻,这四款国产电动车不容错过,高合HiPhi Z科技太绝了

    在接下来几天,广州车展将成为国内汽车行业的焦点所在。作为今年最后一场大秀,本土作战的自主车企蓄势待发,特别是在电动车领域摩拳擦掌,想要进一步扩大市场份额。本文就将介绍四款实力国产车型,它们都是新能源大潮之下全新产物,将会给你带来极佳驾乘体验,都具备成为明星车型的潜力。

    科技 2021年11月17日
  • iPhone 13第三方换屏更难:Face ID会失效 即便官方配件也不行

    苹果对 iPhone 13 系列屏幕的重新设计,意味着第三方维修公司现在更难更换屏幕。因为在尝试更换损坏掉的屏幕,可能会导致失去对 Face ID 的支持。碎屏是最常见的手机故障之一,任何意外的跌落、磕碰、挤压等等都会造成。

    科技 2021年11月20日
  • 口内生产挥发性硫化合物使儿童不喜欢甘蓝类蔬菜

    许多孩子,以及成年人,都不喜欢吃甘蓝类蔬菜,如:花椰菜,卷心菜等。在口腔中,这些蔬菜和唾液中的细菌产生的酶会产生令人不快的硫磺味。现在,研究人员已经发现,这些挥发性化合物的水平在亲子配对中是相似的,这表明口腔中共有的微生物群落。他们还发现挥发性高的硫化合物的食物会导致孩子们讨厌蔬菜。

    生活 2021年9月28日
  • 别克昂科旗2020款配置,别克昂科旗豪华版

    文章长度:0太短了,请勿浪费资源

    科技 2021年12月9日
  • 夏季如何给孩子健脾祛湿?1套手法2碗汤有效防湿气

    一年四季是常识,可不少中医却将一年分成了五部分,分别是:春、夏、长夏、秋、冬。别小看了长夏:“脾主长夏,为后天之本,运化水谷则生机可得。”这句话就是在启发我们,想让孩子脾胃功能健运,长夏是个关键期,做好养脾、健脾的工作,孩子的脾胃功能有不错的进步。

    生活 2021年9月28日
  • 没有二选一的“双11”,电商进入合纵连横时代

    没有二选一的2021年,电商转折的一年。 作者 | 李白玉 来源 | 野马财经 “今年双11战线拉得太长了,各种优惠政策太复杂了,我希望平台好好反思改进,给各位姐妹更好的体感。”说...

    科技 2021年11月15日