C# 10 新特性 —— 补充篇

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 中增加了 record struct,它可以使用这个特性吗?答案是不可以,这一特性仅针对于 record class,在 record struct 中使用会得到一个类似下面的错误

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 type
static async ValueTask<int> ExampleAsync() { ... }

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

[AsyncStateMachine(typeof(<ExampleAsync>d__29))]
[CompilerGenerated]
[AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))] // retained but not necessary anymore
static ValueTask<int> ExampleAsync()
{<ExampleAsync>d__29 stateMachine;stateMachine.<>t__builder = PoolingAsyncValueTaskMethodBuilder<int>.Create(); // <>t__builder now a different typestateMachine.<>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 新特性中的一部分,但是已经可以使用了,需要声明 LangVersionpreview,否则会看到类似下面的一个错误

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 的地方指定泛型委托会报错,错误信息如下:

'DataValiadator' is not a valid named attribute argument because it is not a valid attribute parameter type

Generic Lambda Error

类似的还有一个 Generic Math 的功能也可以预览使用,但是对我来说感觉意义不是特别大,所以就不介绍了,感兴趣的可以参考:https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/

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

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

C# 10 新特性 —— 补充篇相关推荐

  1. C# 9 新特性 —— 补充篇

    C# 9 新特性 -- 补充篇 Intro 前面我们分别介绍了一些 C# 9 中的新特性,还有一些我觉得需要了解一下的新特性,写一篇作为补充. Top-Level Statements 在以往的代码里 ...

  2. JDK8之新特性扩展篇

    转载自 JDK8之新特性扩展篇 BASE64 base64编码解码已经被加入到了jdk8中了. import java.nio.charset.StandardCharsets; import jav ...

  3. Java 10新特性

    Java 10新特性 Java 10是其23年历史中最快的java版本.Java因其缓慢的增长和发展而受到批评,但Java 10刚刚破坏了这一概念.Java 10是一个具有许多未来变化的版本,其范围和 ...

  4. Java 10 新特性概述

    Java 10是其23年历史中最快发布的java版本.Java因其缓慢的增长和发展而受到批评,但Java 10刚刚破坏了这个概念.Java 10是一个具有许多未来变化的版本,其范围和影响可能并不明显, ...

  5. C# 10 新特性 —— 插值字符串优化

    C# 10 新特性 -- 插值字符串优化 Intro 字符串应该是我们平时使用的最多的一个类型,从 C# 6 开始我们开始支持了插值字符串,使得我们可以更方便的进行字符串的操作,现在很多分析器也推荐我 ...

  6. C# 10 新特性 —— Lambda 优化

    C# 10 新特性 -- Lambda 优化 Intro C# 10 对于 Lambda 做了很多的优化,我们可以在 C# 中更加方便地使用委托和 Lambda 了,下面就来看一些示例 Lambda ...

  7. C# 10 新特性 —— CallerArgumentExpression

    C# 10 新特性 -- CallerArgumentExpression Intro C# 10 支持使用 CallerArgumentExpression 来自动地获取调用方的信息,这可以简化我们 ...

  8. C# 10 新特性 —— 命名空间的变化

    C# 10 新特性 -- 命名空间的变化 Intro C# 10 针对命名空间做了一些改变,主要是 Global Usings 和 File-scoped Namespace,我们前面分享的示例其实也 ...

  9. JDK 5 ~ 10 新特性倾情整理

    转载自 JDK 5 ~ 10 新特性倾情整理 最近连 JDK11都在准备发布的路上了,大家都整明白了吗?也许现在大部分人还在用6-8,8的新特性都没用熟,9刚出不久,10-11就不用说了. 为了大家对 ...

最新文章

  1. 安卓app和iosapp开发有什么不同呢?-综合外链_想让卫星软件不“软” 给草根开发者提供的条件得“硬”...
  2. 在疫情防控一线,技术能发挥什么作用?
  3. 访谈实录:网管员如何踏上高薪之路(1)
  4. 文远知行核武器曝光:无人车量产都靠它
  5. 眼图在通信系统中有什么意义_悟空CRM:施行CRM系统对汽车行业有什么意义
  6. PHP手机号中间四位用星号*代替显示
  7. 【学习笔记】7、标准数据类型—字符串
  8. boot lib分离 spring_SpringBoot+MyBatis+MySQL读写分离(实例)A
  9. 批量修改栏目名_Endnote中英文混排批量修改小技巧
  10. php什么是变量6,PHP变量是什么
  11. SpringBoot注解 @Configuration @PropertySource @ConfigurationProperties
  12. WSS2.0 SP2升级到WSS3.0步骤
  13. 479 Largest Palindrome Product 最大回文数乘积
  14. 爬虫之Selenium库
  15. 经典问题莫比乌斯反演gcd(a,b)==kGuGuFishtion好题
  16. 大数据在零售业的应用
  17. 为什么Laravel会成为最成功的PHP框架
  18. 小程序直接跳转公众号的必要条件记录
  19. 荣耀magic3参数配置
  20. c语言一维数组求平均成绩,C语言 计算一维数组平均值(函数).doc

热门文章

  1. 自动以及手动清除手机垃圾文件
  2. html5波浪线条,HTML5 svg炫酷波浪线条动画插件
  3. python实习生面试题_大数据分析实习生面试题库
  4. 4K 海思 联咏 芯片_老电视也有春天,换装海美迪4K电视盒子H7 Plus
  5. linux系统下nginx安装目录和nginx.conf配置文件目录
  6. Linux中一些常用的很巧妙的命令
  7. Ruby 学习笔记3
  8. .text 0.958之间居的中文汉化下载
  9. python多任务编程_python线程的多任务编程
  10. ResourceManager中的Resource Estimator框架介绍与算法剖析