经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C# 9 新特性 —— 补充篇
来源:cnblogs  作者:WeihanLi  时间:2021/1/11 10:04:46  对本文有异议

C# 9 新特性 —— 补充篇

Intro

前面我们分别介绍了一些 C# 9 中的新特性,还有一些我觉得需要了解一下的新特性,写一篇作为补充。

Top-Level Statements

在以往的代码里,一个应用程序必须要有 Main 方法才能运行,从 C# 9 开始,支持没有 Main 方法的程序,实际编译之后还是会有一个 Main 方法的,使用示例如下:

  1. using static System.Console;
  2. WriteLine("Hello World!");

实际编译出来的结果如下:

实际会生成一个没有命名空间的 <Program>$ 的类型,类中定义的有一个名称是 <Main>$ 的静态方法

Improved discards in lambda input parameter

从 C# 7.2 开始,我们可以使用 _ 来代表一个不使用的变量,废弃变量,但是在 lambda 表达式里默认不能有同名的参数名,从 C# 9 开始,支持多个参数同时使用 _ 来表示,如下所示:

  1. Func<int, int, int> constant = (_, _) => 42;

Attributes for local function

从 C# 9 开始,我们可以在局部方法(本地方法)上设置 Attribute

  1. public static void MainTest()
  2. {
  3. InnerTest();
  4. [MethodImpl(MethodImplOptions.Synchronized)]
  5. void InnerTest()
  6. {
  7. Console.WriteLine(nameof(InnerTest));
  8. }
  9. }

Partition methods

在 C# 2.0 之后就支持了分部类,通常分部类会出现在动态代码生成的地方,对于想要将一个类型拆分到多个文件里,我们通常也会考虑用到分部类。

C# 3.0 开始支持了分部方法,但是功能比较弱,使用起来有一些限制:

  • 分部类型各部分中的签名必须匹配。
  • 方法必须返回 void。
  • 不允许使用访问修饰符。 分部方法是隐式 private 的。

C# 9 增强了分部方法的支持,分部方法的使用,只能在一个地方有方法体,目前主要是为了 Source Generator 引入了这个语言特性,可以在一个地方定义方法,在另外一个地方实现方法体,示例如下:

  1. partial class PartialMethod
  2. {
  3. public static partial void MainTest();
  4. static partial void Test1();
  5. }
  6. partial class PartialMethod
  7. {
  8. public static partial void MainTest()
  9. {
  10. Test1();
  11. Console.WriteLine("Partial method works");
  12. }
  13. }

符合 C# 3.0 分部方法规则的允许没有方法体,否则必须要有方法体

ModuleInitializer

Source Generator 除了上面的分部方法之外,还引入了一个 ModuleInitializer 的概念,就像它的名字,模块初始化器,当用到某个模块的时候就会调用对应的 ModuleInitializer 方法进行初始化操作

ModuleInitializer 定义如下:

  1. namespace System.Runtime.CompilerServices
  2. {
  3. [AttributeUsage(AttributeTargets.Method, Inherited = false)]
  4. public sealed class ModuleInitializerAttribute : Attribute
  5. {
  6. }
  7. }

使用示例如下:

  1. internal static class ModuleInitializerSample
  2. {
  3. /// <summary>
  4. /// Initializer for specific module
  5. ///
  6. /// Must be static
  7. /// Must be parameter-less
  8. /// Must return void
  9. /// Must not be a generic method
  10. /// Must not be contained in a generic class
  11. /// Must be accessible from the containing module
  12. /// </summary>
  13. [ModuleInitializer]
  14. public static void Initialize()
  15. {
  16. Console.WriteLine($"{nameof(ModuleInitializerAttribute)} works");
  17. }
  18. }

ModuleInitlializer 对应的方法有几个要求

  • 必须是静态方法
  • 不能有方法参数,无参数方法
  • 方法没有返回值,返回类型必须是 void
  • 不能是泛型方法
  • 不能在泛型类中
  • 必须能够被所在模块访问的到(至少是 internal)


来看反编译的代码,可以看到有一个 Module 的类,在这个 Module 类的静态构造方法里会去调用声明为 ModuleInitializer 的方法

Function Pointer

C# 9 支持方法指针,对委托进一步的”C++化“,进一步提升性能,属于非安全代码,使用需开启 unsafe,使用示例如下:

  1. public static unsafe void MainTest()
  2. {
  3. delegate*<int, int, int> pointer = &Test;
  4. var result = pointer(1, 1);
  5. Console.WriteLine(result);
  6. }
  7. private static int Test(int num1, int num2)
  8. {
  9. Console.WriteLine($"Invoke in {nameof(Test)}, {num1}_{num2}");
  10. return num1 + num2;
  11. }

Static Anoymouse Method

C# 9 开始支持在匿名方法或者表达式前声明 static,声明 static 之后就不能使用实例变量,只能使用静态变量,如下所示:

  1. internal class StaticAnonymousMethod
  2. {
  3. private readonly int num = 1;
  4. public void MainTest()
  5. {
  6. // anonymous method
  7. Action action = () => { Console.WriteLine(num); };
  8. Action action1 = static () => { };// can not access `num`
  9. //expression
  10. Expression<Func<int, bool>> expression = i => i > num;
  11. Expression<Func<int, bool>> expression1 = static i => i > 1;// can not access `num`
  12. }
  13. }

Covariant Return Type

C# 9 开始支持返回类型的 Covariant(协变), 对于 override 方法可返回从重写基方法的返回类型派生的类型。 这对于record和其他支持工厂方法的类型会很有用。可以参考下面的使用示例:

  1. internal class CovariantReturnType
  2. {
  3. private abstract class Operation
  4. {
  5. }
  6. private abstract class OperationFactory
  7. {
  8. public abstract Operation GetOperation();
  9. }
  10. private class AddOperation : Operation
  11. {
  12. }
  13. private class AddOperationFactory : OperationFactory
  14. {
  15. // 返回类型协变,返回具体的类型而不是抽象类中声明的类型
  16. public override AddOperation GetOperation()
  17. {
  18. return new();
  19. }
  20. }
  21. public static void MainTest()
  22. {
  23. var factory = new AddOperationFactory();
  24. factory.GetOperation();
  25. }
  26. }

More

除此之外还有一些小的更新特性,详细可以参考文末给出的官方文档。

Reference

原文链接:http://www.cnblogs.com/weihanli/p/14244158.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号