C# 9 特性二

介绍

接下来我将给大家重点介绍一下.Net 6 之后的一些新的变更,文章都是来自于外国大佬的文章,我这边进行一个翻译,并加上一些自己的理解和解释。

源作者链接:https://blog.okyrylchuk.dev/a-comprehensive-overview-of-c-9-features

正文

静态匿名函数

匿名函数并不便宜。Lambda 可能会无意中捕获局部变量,并可能导致意外的额外分配。C# 9 中 lambda的static修饰符有助于避免这种情况。

[MemoryDiagnoser]
public class Benchmark
{
    [Benchmark]
    public void AnounymousFunction()
    {
        var list = new List<int> { 1, 2, 3 };
        int y = 2;
        list.ForEach(x => x *= y);
    }
    [Benchmark]
    public void StaticAnounymousFunction()
    {
        var list = new List<int> { 1, 2, 3 };
        const int y = 2;
        list.ForEach(static x => x *= y);
    }
}

局部函数的属性

在 C# 9 中允许本地函数具有属性。本地函数上的参数也允许具有属性。

class Program
{
    static void Main()
    {
        [Obsolete("Attribute on local function")]
        void LocalFunction()
        {
            Console.WriteLine("Hello World!");
        }
        LocalFunction();
    }
}

Lambda丢弃参数

C# 9 中对 lambda 和匿名函数的小幅改进允许丢弃它们的参数。所以意图很明确 - 参数未使用。该功能对 WinForms 编码很有用。

class Button
{
    public event EventHandler Click;
}
static void Main()
{
    void PrintHelloWorld()
    {
        Console.WriteLine("Hello World!");
    }
    Button button = new();
    button.Click += (_, _) => PrintHelloWorld();
}

无约束类型参数注解

在 C# 8 中,?注释只能应用于显式约束为值或引用类型的类型参数。在 C# 9 中,它可以应用于任何类型参数,没有约束。

#nullable enable
class Example
{
    // handle both reference and value types
    public void DoSomething<T>(T? param)
    { }
}

static void Main()
{
    var example = new Example()
    // reference type, not null
    example.DoSomething(new object());
    // reference type, null
    example.DoSomething<object>(null);
    // value type
    example.DoSomething(DateTime.Today);
}

默认约束

为了允许?对重写方法上的类型参数进行注释,C# 8 允许对值和引用类型进行显式约束。C# 9 允许where T: default对不受引用或值类型约束的重写方法进行新约束。

class Base
{
    // handle both reference and value types
    public virtual void DoSomething<T>(T? param) { }
}

class Overridden : Base
{
    // override with default constraint
    // handle both reference and value types
    public override void DoSomething<T>(T? param)
        where T : default
    { }
}

static void Main()
{
    Base @base = new();
    @base.DoSomething(1); // value type
    @base.DoSomething(new object()); // ref type, not null
    @base.DoSomething<object>(null); // ref type, nul

    Overridden overriden = new();
    overriden.DoSomething(1); // value type
    overriden.DoSomething(new object()); // ref type, not null
    overriden.DoSomething<object>(null); // ref type, nul
}

扩展分部方法

C# 8 对部分方法有几个限制:

  • 必须有void返回类型。
  • 不能有out参数。
  • 不能有任何可访问性(隐式private)。

C# 9 消除了这些限制。

class Program
{
    partial class Example
    {
        // Other than void return type is allowed
        public partial int A();
        // Access modifiers are allowed
        public partial void B();
        // Out params are allowed
        public partial void C(out int param);
    }
    partial class Example
    {
        public partial int A() => 0;
        public partial void B() { }
        public partial void C(out int param)
        {
            param = 0;
        }
    }
    static void Main(string[] args)
    {
    }
}

结语

联系作者:加群:867095512 @MrChuJiu

公众号

posted @ 2022-02-21 10:27  初久的私房菜  阅读(230)  评论(0编辑  收藏  举报
作者:初久的私房菜
好好学习,天天向上
返回顶部小火箭
好友榜:
如果愿意,把你的博客地址放这里
张弛:https://blog.zhangchi.fun/