• C# 13(.Net 9) 中的新特性 - 扩展类型


    C# 13 即 .Net 9 按照计划会在2024年11月发布,目前一些新特性已经定型,今天让我们来预览一个比较大型比较重要的新特性:

    扩展类型 Extension types#

    在5月份的微软 Build 大会中的 What’s new in C# 13 会议上,两位大佬花了很长的篇幅来演示这个特性。
    这个特性一直是大家很关心的,在 github 的 issue 上讨论的也是如火如荼,当然微软也鸽了好多年:(
    首先,让我们来回顾一下 C# 中的扩展方法

    using System;
    
    var zhangsan = new Person();
    Console.WriteLine(zhangsan.GetAge());
    
    public class Person
    {
        public string Name { get; set; } 
        public DateTime Birthday { get; set; }
    }
    
    public static class PersonExtension
    {
        public static int GetAge(this Person person) => DateTime.Now.Year - person.Birthday.Year;
    }
    

    以上代码演示了一个扩展方法声明方式及使用方法。
    我们在不侵入 Person 类的基础上为 Person 类扩展了一个 GetAge() 的方法,虽然已经可以很方便的扩展出一些方法来,但是问题也是显而易见的,例如必须声明在静态类中、语法看起来很怪异、只能扩展方法而不能扩展属性等等。
    于是,在即将到来的 C# 13 中,我们可以这样

    var zhangsan = new Person();
    Console.WriteLine(zhangsan.GetAge());
    
    public implicit extension PersonExtension for Person
    {
        public int GetAge() => DateTime.Now.Year - this.Birthday.Year;
    }
    

    怎么样,语义是不是清晰了很多?
    进一步的,年龄应该是一个属性而不应该是一个方法

    var zhangsan = new Person();
    Console.WriteLine(zhangsan.Age);
    
    public implicit extension PersonExtension for Person
    {
        public int Age => DateTime.Now.Year - this.Birthday.Year;
    }
    

    困扰多年的如何扩展属性的问题终于得到了解决。

    implicit extension / explicit extension#

    在上一个例子,不知道大家有没有注意到关键字是 implicit extension,那么很显然,会有一个对应的 explicit extension,下面让我们来看看花活

    var zhangsan = new Person();
    if(zhangsan.IsStudent)
    {
        Student zhangsanAsStudent = zhangsan;
        Console.WriteLine(zhangsanAsStudent.Grade);
    }
    
    public implicit extension PersonExtension for Person
    {
        public int Age => DateTime.Now.Year - this.Birthday.Year;
        public bool IsStudent => this.Age < 18;
    }
    
    public explicit extension Student for Person
    {
        public string Grade => "五年级";
    }
    

    可以看到,这里有一个显示扩展,显式扩展可以创建原始类的投影或子类。当你要基于扩展类型添加条件方法或属性时,这可能很有用。

    当然,扩展静态方法也是没问题的

    var zhangsan = Person.Create();
    
    public implicit extension PersonExtension for Person
    {
        public static Person Create() => new Person();
    }
    

    当然,系统类型也是支持的

    Console.WriteLine("World".SayHello());
    
    public implicit extension StringExtension for string
    {
        public string SayHello() => "Hello" + this;
    }
    

    结尾#

    我想这个特性是很大的一个改变,或许可以改进 C# 代码的组织方式,有望提高代码的可读性、可维护性和表现力。通过允许开发人员在不修改原始代码的情况下向现有类添加功能,它可以促进代码重用并减少修改原始类的需要。
    另外据了解,这个特性以及相关特性,例如扩展接口等等,并不会在 C# 13 (.Net 9) 中完整的放出来,而是会在后续版本中逐渐解锁。

    参考#

    https://build.microsoft.com/en-US/sessions/689e5104-72e9-4d02-bb52-77676d1ec5bc?source=sessions
    https://devblogs.microsoft.com/dotnet/dotnet-build-2024-announcements/
    https://github.com/dotnet/csharplang/issues/5497

    作者:Rwing

    出处:https://www.cnblogs.com/Rwing/p/18261641/Csharp_13_dot_net_9_preview_extension_types

    版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

  • 相关阅读:
    【超详细】CentOS 7安装MySQL 5.7【安装及密码配置、字符集配置、远程连接配置】
    概念解析 | 心脏电活动和机械活动之间的关系
    java毕业设计企业门户网站源码+lw文档+mybatis+系统+mysql数据库+调试
    Spring boot环境搭建
    详解如何利用PHP实现RPC
    某酒管集团-单例模式对性能的影响及思考
    区块链游戏解说:什么是 Arcade Champion
    关于割接9000W数据的一些事
    代码随想录算法训练营19期第49天
    零基础学Python--机器学习(一):人工智能与机器学习概述
  • 原文地址:https://www.cnblogs.com/Rwing/p/18261641/Csharp_13_dot_net_9_preview_extension_types