博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 9 新特性 —— 补充篇
阅读量:4034 次
发布时间:2019-05-24

本文共 4074 字,大约阅读时间需要 13 分钟。

C# 9 新特性 —— 补充篇

Intro

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

Top-Level Statements

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

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

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

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

Improved discards in lambda input parameter

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

Func
 constant = (_, _) => 42;

Attributes for local function

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

public static void MainTest(){    InnerTest();    [MethodImpl(MethodImplOptions.Synchronized)]    void InnerTest()    {        Console.WriteLine(nameof(InnerTest));    }}

Partition methods

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

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

  • 分部类型各部分中的签名必须匹配。

  • 方法必须返回 void。

  • 不允许使用访问修饰符。分部方法是隐式 private 的。

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

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 分部方法规则的允许没有方法体,否则必须要有方法体

ModuleInitializer

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 对应的方法有几个要求

  • 必须是静态方法

  • 不能有方法参数,无参数方法

  • 方法没有返回值,返回类型必须是 void

  • 不能是泛型方法

  • 不能在泛型类中

  • 必须能够被所在模块访问的到(至少是 internal)

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

Function Pointer

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;}

Static Anoymouse Method

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
> expression = i => i > num;        Expression
> expression1 = static i => i > 1;// can not access `num`    }}

Covariant Return Type

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();    }}

More

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

Reference

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

  • https://github.com/WeihanLi/SamplesInPractice/tree/master/CSharp9Sample

转载地址:http://wfudi.baihongyu.com/

你可能感兴趣的文章
Error:No converter found for return value of type
查看>>
请自觉收藏,Linux常用基本命令
查看>>
mysql常见存储引擎简介
查看>>
Redis的持久化机制,你了解吗
查看>>
微视linux 根文件系统之二 bootloader(以uboot为例)的准备
查看>>
微视linux 根文件系统之三 内核解压缩
查看>>
数据结构与算法之图的DFS算法
查看>>
数据结构与算法 递归的理解
查看>>
微视linux 通用块层之bio
查看>>
微视linux 进程的当前目录
查看>>
慢慢欣赏linux 页面回收续
查看>>
微视linux内核 x86_32内核启动
查看>>
链接脚本
查看>>
微视linux 内存水线划分
查看>>
微视linux 文件系统之打开文件返回只读
查看>>
微视linux 文件系统之打开文件create模式
查看>>
微视linux bash返回值
查看>>
慢慢欣赏linux ext3文件系统 直接块和间接块
查看>>
好用的博客和网站
查看>>
创建特定文件
查看>>