More about C# 9express
C# 9 新特性 —— 补充篇前面咱们分别介绍了一些 C# 9 中的新特性,还有一些我以为须要了解一下的新特性,写一篇做为补充。安全
在以往的代码里,一个应用程序必需要有 Main 方法才能运行,从 C# 9 开始,支持没有 Main 方法的程序,实际编译以后仍是会有一个 Main 方法的,使用示例以下:less
using static System.Console; WriteLine("Hello World!");
实际编译出来的结果以下:ide
实际会生成一个没有命名空间的 的类型,类中定义的有一个名称是 的静态方法性能
从 C# 7.2 开始,咱们可使用 _ 来表明一个不使用的变量,废弃变量,可是在 lambda 表达式里默认不能有同名的参数名,从 C# 9 开始,支持多个参数同时使用 _ 来表示,以下所示:spa
Funcconstant = (_, _) => 42;
从 C# 9 开始,咱们能够在局部方法(本地方法)上设置 Attribute3d
public static void MainTest() { InnerTest(); [MethodImpl(MethodImplOptions.Synchronized)] void InnerTest() { Console.WriteLine(nameof(InnerTest)); } }
在 C# 2.0 以后就支持了分部类,一般分部类会出如今动态代码生成的地方,对于想要将一个类型拆分到多个文件里,咱们一般也会考虑用到分部类。指针
C# 3.0 开始支持了分部方法,可是功能比较弱,使用起来有一些限制:blog
C# 9 加强了分部方法的支持,分部方法的使用,只能在一个地方有方法体,目前主要是为了 Source Generator 引入了这个语言特性,能够在一个地方定义方法,在另一个地方实现方法体,示例以下:ci
partial class PartialMethod { public static partial void MainTest(); static partial void Test1(); } partial class PartialMethod { public static partial void MainTest() { Test1(); Console.WriteLine("Partial method works"); } }
符合 C# 3.0 分部方法规则的容许没有方法体,不然必需要有方法体
Source Generator 除了上面的分部方法以外,还引入了一个 ModuleInitializer 的概念,就像它的名字,模块初始化器,当用到某个模块的时候就会调用对应的 ModuleInitializer 方法进行初始化操做
ModuleInitializer 定义以下:
namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Method, Inherited = false)] public sealed class ModuleInitializerAttribute : Attribute { } }
使用示例以下:
internal static class ModuleInitializerSample { ////// Initializer for specific module /// /// Must be static /// Must be parameter-less /// Must return void /// Must not be a generic method /// Must not be contained in a generic class /// Must be accessible from the containing module ///[ModuleInitializer] public static void Initialize() { Console.WriteLine($"{nameof(ModuleInitializerAttribute)} works"); } }
ModuleInitlializer 对应的方法有几个要求
来看反编译的代码,能够看到有一个 Module 的类,在这个 Module 类的静态构造方法里会去调用声明为 ModuleInitializer 的方法
C# 9 支持方法指针,对委托进一步的”C++化“,进一步提高性能,属于非安全代码,使用需开启 unsafe,使用示例以下:
public static unsafe void MainTest() { delegate*pointer = &Test; var result = pointer(1, 1); Console.WriteLine(result); } private static int Test(int num1, int num2) { Console.WriteLine($"Invoke in {nameof(Test)}, {num1}_{num2}"); return num1 + num2; }
C# 9 开始支持在匿名方法或者表达式前声明 static,声明 static 以后就不能使用实例变量,只能使用静态变量,以下所示:
internal class StaticAnonymousMethod { private readonly int num = 1; public void MainTest() { // anonymous method Action action = () => { Console.WriteLine(num); }; Action action1 = static () => { };// can not access `num` //expression Expression<Func> expression = i => i > num; Expression<Func> expression1 = static i => i > 1;// can not access `num` } }
C# 9 开始支持返回类型的 Covariant(协变), 对于 override 方法可返回从重写基方法的返回类型派生的类型。 这对于record和其余支持工厂方法的类型会颇有用。能够参考下面的使用示例:
internal class CovariantReturnType { private abstract class Operation { } private abstract class OperationFactory { public abstract Operation GetOperation(); } private class AddOperation : Operation { } private class AddOperationFactory : OperationFactory { // 返回类型协变,返回具体的类型而不是抽象类中声明的类型 public override AddOperation GetOperation() { return new(); } } public static void MainTest() { var factory = new AddOperationFactory(); factory.GetOperation(); } }
除此以外还有一些小的更新特性,详细能够参考文末给出的官方文档。