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

net · 浏览次数 : 9

小编点评

C# 13(即.Net 9)计划于2024年11月发布,将带来一系列新特性和改进。其中一个重要特性是扩展类型(Extension Types),它允许开发人员在不修改原始代码的情况下向现有类添加功能。扩展类型分为隐式扩展(implicit extension)和显式扩展(explicit extension)两种。 隐式扩展不需要在类前添加额外的语法结构,使得扩展方法更易于使用。例如,以下代码为Person类扩展了一个隐式扩展方法,用于计算年龄: ```csharp public static int GetAge(this Person person) => DateTime.Now.Year - person.Birthday.Year; ``` 显式扩展则需要使用特殊的语法结构,明确指出这是一个扩展方法。例如,以下代码为Person类扩展了一个显式扩展方法,用于判断学生身份: ```csharp public implicit extension PersonExtension for Person { public int Age => DateTime.Now.Year - this.Birthday.Year; public bool IsStudent => this.Age < 18; } ``` 此外,扩展类型还可以用于扩展属性。例如,以下代码为Person类扩展了一个隐式属性,用于获取学生所在的年级: ```csharp public implicit extension PersonExtension for Person { public int Age => DateTime.Now.Year - this.Birthday.Year; public bool IsStudent => this.Age < 18; } ``` 扩展方法还可以用于扩展静态方法。例如,以下代码为Person类扩展了一个静态方法,用于创建一个新的Person实例: ```csharp public implicit extension PersonExtension for Person { public static Person Create() => new Person(); } ``` 总之,扩展类型是C# 13的一个重要特性,它可以帮助开发人员更轻松地向现有类添加功能,提高代码的可读性、可维护性和表现力。需要注意的是,这些特性将在后续版本中逐渐解锁,而非一次性全部放出。

正文

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

结尾

我想这个特性是很大的一个改变,或许可以改进 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

与C# 13(.Net 9) 中的新特性 - 扩展类型相似的内容:

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

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

.NET周报【1月第2期 2023-01-13】

国内文章 【ASP.NET Core】按用户等级授权 https://www.cnblogs.com/tcjiaan/p/17024363.html 本文介绍了ASP.NET Core如何按照用户等级进行授权。 在 C# 9 中使用 foreach 扩展 https://www.cnblogs.co

【长文】带你搞明白Redis

Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每...

开源GTKSystem.Windows.Forms框架让C# winform支持跨平台运行

目录 一、简介 二、GTKSystem.Windows.Forms框架的优势 三、支持界面皮肤主题定制 四、多种控件支持 五、支持Dock、Anchor、SplitContainer布局缩放 六、支持扩展控件 一、简介 微软原生的.net winform只支持在windows平台下运行,只中一个原因

C#S7.NET实现西门子PLCDB块数据采集的完整步骤

前言 本文介绍了如何使用S7.NET库实现对西门子PLC DB块数据的读写,记录了使用计算机仿真,模拟PLC,自至完成测试的详细流程,并重点介绍了在这个过程中的易错点,供参考。 用到的软件: 1.Windows环境下链路层网络访问的行业标准工具(WinPcap_4_1_3.exe)下载链接:http

.NET周报【1月第3期 2023-01-20】

这应该是2023年农历新年前的最后一篇.NET周报,再次预祝大家新年快乐! 国内文章 看我是如何用C#编写一个小于8KB的贪吃蛇游戏的 https://www.cnblogs.com/InCerry/p/building-a-self-contained-game-in-c-under-8-kilo

C++(Qt)-GIS开发-简易瓦片地图下载器

Qt-GIS开发-简易瓦片地图下载器 目录Qt-GIS开发-简易瓦片地图下载器1、概述2、安装openssl3、实现效果4、主要代码4.1 算法函数4.2 瓦片地图下载url拼接4.3 多线程下载5、源码地址6、参考 更多精彩内容 个人内容分类汇总 GIS开发 1、概述 支持单线

2.1 C++ STL 数组向量容器

Vector容器是C++ STL中的一个动态数组容器,可以在运行时动态地增加或减少其大小,存储相同数据类型的元素,提供了快速的随机访问和在末尾插入或删除元素的功能。该容器可以方便、灵活地代替数组,容器可以实现动态对数组扩容删除等各种复杂操作,其时间复杂度`O(l)常数阶`,其他元素的插入和删除为`O(n)线性阶`,其中n为容器的元素个数,vector具有自动的内存管理机制,对于元素的插入和删除可动

4.1 C++ STL 动态链表容器

List和SList都是C++ STL中的容器,都是基于双向链表实现的,可以存储可重复元素的特点。其中,List内部的节点结构包含两个指针一个指向前一个节点,一个指向后一个节点,而SList只有一个指针指向后一个节点,因此相对来说更节省存储空间,但不支持反向遍历,同时也没有List的排序功能。双向链表的数据元素可以通过链表指针串接成逻辑意义上的线性表,不同于采用线性表顺序存储结构的`Vector`

C++ bitset 用法和应用

C++的 bitset 在 bitset 头文件中,它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。 下面是具体用法 构造函数 bitset常用构造函数有四种,如下 bitset<4> bitset1; //无参构造,长度为4,默认每一位为0 bitset<8> bit