百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

C#12那些有意思的特性

ztj100 2024-12-10 22:17 19 浏览 0 评论

C#在过去十年中经历了很多变化。从开源语言到新的跨平台框架,再到年度发布而不是每3 年一轮回的迭代。通过这一切,C#和.NET保持了一定的热度和流行性。在这篇博文中,将简要介绍 C# 语言设计团队面临的日常活动和挑战。你将在即将推出的 C# 12版本以及以后的版本中看到他们正在处理的内容。

为了忠于开源文化,C# 设计团队将其整个活动转移到公共 GitHub 存储库(GitHub - dotnet/csharplang: The official repo for the design of the C# programming language)中。在里面,您可以看到语言规范、新功能提案、问题、建议、问题和有价值的语言设计会议摘要(LDM csharplang/meetings at main · dotnet/csharplang · GitHub)。深入了解这些会议的内容并了解他们正在进行的讨论类型是很有趣的。这些人必须考虑编译器限制、内存和性能影响、语法挑战以及与现有 C# 代码的向后兼容性等问题。但我会把这个问题留给他们,我们只讨论结果。下面是一些即将推出的 C# 12及更高版本的最有趣的提案。

1. 主构造函数

主构造函数是 C# 12的主要功能。其主要思想是在构造函数中接收参数并将其保存为私有成员时使用更细的语法。下面是新语法的示例:

public class Person (string firstName, string lastName)
{
    string FullName => `{firstName} {lastName}`; 
}

这将与编写以下内容相同:

public class Person
{
	private string firstName;
	private string lastName;
	
	public Person(string firstName, string lastName)
	{
		this.firstName = firstName;
		this.lastName = lastName;
	}
    
    string  FullName => `{firstName} {lastName}`;
}

是不是觉得语法看起来很熟悉,那就对的,它与 C# 9中引入的record(璁板綍 - C# 鍙傝€? | Microsoft Learn)非常相似。但也有区别:

  • record是不可变的,而具有主构造函数的类将具有与常规类相同的概念用法(代码少一点)。
  • 在record中,构造函数参数保存为公共不可变属性,而在类中,它们将保存为私有字段。
  • 您可以在record中使用with关键字来创建修改的副本,但不能在具有主构造函数的类中使用。

这就是它的要点。但是如果我们仔细想想,他其实还有一些悬而未决的问题。比如当我们需要多个构造函数时会发生什么?它如何与基类一起工作?这么一看似乎语言设计并不像听起来那么容易了[呲牙]。感兴趣的朋友可以在官方提案中阅读所有相关信息(csharplang/proposals/primary-constructors.md at main · dotnet/csharplang · GitHub),并查看语言设计会议摘要LDM-2022-10-17和LDM-2023-01-18。

2. 半自动属性(和关键字field)

C#围绕属性进行了很多开发。半属性提案(csharplang/proposals/semi-auto-properties.md at main · dotnet/csharplang · GitHub)省去了创建支持字段的麻烦。相反,我们将能够使用新关键字field(正在提议)来访问该成员。下面是语法示例:

public class Point
{
    public int X { get { return field; } set { field = value; } }
    public int Y { get { return field; } set { field = value; } }
}

这相当于常规的自动属性

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }
}

此代码是在后台为两者生成的:

public class Point
{
    private int __x;
    private int __y;
    public int X { get { return __x; } set { __x = value; } }
    public int Y { get { return __y; } set { __y = value; } }
}

使用半自动属性,我可以写这样的东西:

public class LazyInit
{
    public string Value => field ??= ComputeValue();
    private static string ComputeValue() { /*...*/ }
}

3. 基于IEnumerables的列表模式匹配

C# 12中列表模式匹配的扩展其实并没有太多优化。使用python的朋友应该对这个模式识别匹配相当熟悉,但考虑到使用c#的同学可能对此较为陌生,这似乎也就变得值得一谈了[憨笑]。这个功能是对列表和数组的强大模式匹配功能,包括通配符和丢弃符。在 C#12中,它从列表和数组(在C# 11中引入)扩展到任何集合。以下是一些示例:

var arr = new[] {1,2,3}; // works with arrays and lists (e.g new List<int>() {1,2,3})
Console.WriteLine(arr is [1,2,3] ); // true (list pattern)
Console.WriteLine(arr is [1,_,3] ); // true (with discard)
Console.WriteLine(arr is [1,2] ); // false
Console.WriteLine(arr is [1, ..] ); // true (slice pattern)

switch (arr) {
    case [..,3]:
        ...
        break;
    case [_,2,_]:
        ...
        break;
    default:
        ...
        break;
}

var y = arr switch {
    [1]=> "foo",
    [1,2,_] => "bar",
    _ => "zing" // default   
};

// Following doesn't work in C# 11, but will (hopefully) work in C# 12
var rng = Enumerable.Range(1,3);// 1,2,3
Console.WriteLine(rng is [1,2,3] ); // true
Console.WriteLine(rng is [1,_,3] ); // true
Console.WriteLine(rng is [1,2] ); // false
Console.WriteLine(rng is [1, ..] ); // true

4. 联合类型

联合类型之前也存在于其他语言中,比如 TypeScript。联合是一种表示变量的方法,该变量可以是多种类型之一。例如,在 TypeScript 中,您可以编写以下内容:

type BoolOrNumber = boolean | number;
const a: BoolOrNumber = false; // ok
const b: BoolOrNumber = 5; // ok
const c: BoolOrNumber = 'asdf'; // error

function Foo(x: BoolOrNumber) {
	console.log(typof x); // will be either "boolean" or "number"
}

在 C# 中,有一个提议就是这样做的。建议的语法类似于TypeScript中的语法:

A | B myUnion1 = new A(); // ok
A | B myUnion2 = new B(); // ok

public void Foo(A | B union) // also OK
{
    if(union is A a)
    {
        ...
    }
    if (union is B b)
    {
        ...
    }
}

这种联合称为“纯联合”(Pure Union)或“类型联合”(Type Union)。但是,该提案并没有包括将联合类型定义为新类型的语法。例如,我们并不能进行这种声明type BoolOrNumber = boolean | number。

这种联合类型使用起来还是非常方便的,但是也可能随之带来代码阅读上的不便。不管怎么样,如果有兴趣的朋友可以参阅Proposal: Fast, Efficient Unions · Issue #7016 · dotnet/csharplang · GitHub来了解更多。

写在最后

在这里,我们简单介绍了下一些C#潜在有趣的功能,意图让朋友们可以了解这些新功能都是如何开发出来的。

如果有兴趣了解有关即将推出的 C# 功能的更多信息,可以从查看活动语言建议开始,尽管阅读起来并不轻松。除了提案之外,还可以查看每周会议摘要和笔记。最后,还可以查看堆积如山的讨论线程和语言创意。由于它是开源的,我们甚至可以自己贡献。

对了忘记说了,如果想要尝鲜一些Preview的功能,我们可以在自己的计算机上安装Visual Studio Preview 和.Net的Preview版本(GitHub - dotnet/installer: .NET SDK Installer)[得意]。

最后,Happy Coding Happy Life[呲牙]

相关推荐

Docker安全开放远程访问连接权限(docker 远程授权访问)

1、Docker完全开放远程访问Docker服务完全开放对外访问权限操作如下:#开启端口命令(--permanent永久生效,没有此参数重启后失效)firewall-cmd--zone=pu...

SpringCloud系列——4OpenFeign简介及应用

学习目标什么是OpenFeign以及它的作用RPC到底怎么理解OpenFeign的应用第1章OpenFeign简介在前面的内容中,我们分析了基于RestTemplate实现http远程通信的方法。并...

Spring Boot集成qwen:0.5b实现对话功能

1.什么是qwen:0.5b?模型介绍:Qwen1.5是阿里云推出的一系列大型语言模型。Qwen是阿里云推出的一系列基于Transformer的大型语言模型,在大量数据(包括网页文本、书籍、代码等)...

JDK从8升级到21的问题集(jdk8升级到11)

一、背景与挑战1.升级动因oOracle长期支持策略o现代特性需求:协程、模式匹配、ZGC等o安全性与性能的需求oAI新技术引入的版本要求...

大白话详解Spring Cloud服务降级与熔断

1.Hystrix断路器概述1.1分布式系统面临的问题复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。这就造成有可能会发生...

面试突击43:lock、tryLock、lockInterruptibly有什么区别?

在Lock接口中,获取锁的方法有4个:lock()、tryLock()、tryLock(long,TimeUnit)、lockInterruptibly(),为什么需要这么多方法?这些方法都有...

了解网络编程 TCP/IP 协议与UDP 协议

因为iP地址比较难记忆,很多情况下可以使用域名代替iP地址。1.TCP/IP协议与UDP协议通过IP地址与端口号确定计算机在网络中的位置后,接下来考虑通讯的问题:因为不同计算机的软硬件平台...

Semaphore与Exchanger的区别(semaphore和signal)

Semaphore和Exchanger是Java并发编程中两个常用的同步工具类,它们都可以用于协调多个线程之间的执行顺序和状态,但它们的作用和使用方式有所不同:Semaphore类表示一个...

Java教程:什么是分布式任务调度?怎样实现任务调度?

通常任务调度的程序是集成在应用中的,比如:优惠卷服务中包括了定时发放优惠卷的的调度程序,结算服务中包括了定期生成报表的任务调度程序...

java多线程—Runnable、Thread、Callable区别

多线程编程优点:进程之间不能共享内存,但线程之间共享内存非常容易。系统创建线程所分配的资源相对创建进程而言,代价非常小。Java中实现多线程有3种方法:继承Thread类实现Runnable...

工厂模式详解(工厂模式是啥意思)

工厂模式详解简单工厂简单工厂模式(SimpleFactoryPattern)是指由一个工厂对象决定创建出哪一种产品类的实例。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的...

我们程序员眼中的母亲节(你眼中的程序员是什么样子的?程序员的薪酬如何?)

导语:对于我们成人来说,尤其是漂泊在外的程序员,陪伴父母的时间太少了。每逢佳节倍思亲,我们流浪外在的游子应该深有感触。母亲,是世界上最伟大的人,她承载着对我们的爱,更是负担和压力。我们作为子女,只会嫌...

死锁的 4 种排查工具(死锁检测方法要解决两个问题)

死锁(DeadLock)指的是两个或两个以上的运算单元(进程、线程或协程),都在等待对方停止执行,以取得系统资源,但是没有一方提前退出,就称为死锁。死锁示例接下来,我们先来演示一下Java中最简...

1. 工厂模式详解(工厂模式示例)

我们的项目代码也是由简而繁一步一步迭代而来的,但对于调用者来说却是越来越简单化。简单工厂模式简单工厂模式(SimpleFactoryPattern)是指由一个工厂对象决定创建出哪一种产品类的实例。...

Jmeter(二十):jmeter对图片验证码的处理

jmeter对图片验证码的处理在web端的登录接口经常会有图片验证码的输入,而且每次登录时图片验证码都是随机的;当通过jmeter做接口登录的时候要对图片验证码进行识别出图片中的字段,然后再登录接口中...

取消回复欢迎 发表评论: