C#12 的强大功能:日常编码的 4 种创新方式

作者:微信公众号:【架构师老卢】
3-17 14:46
38

概述:.NET 8 将于 11 月推出,Microsoft 推出了 C# 12.0 预览版,让我们大吃一惊。在第 7 次迭代中已经可以体验到以下出色的语言版本。人们的兴奋已经越来越高了——C# 12.0 即将到来!这次会有什么新东西吗?听好了,我可能已经剧透了:是的!如何启用新版本下载您想要的预览版本在代码编辑器关闭时安装它打开代码编辑器并更改 .csproj 文件(更多内容见下文)看看 C#12.0 是值得的,也是有益的。许多新功能是期待已久的。不仅来自我的 POV。因此,让我们在计算机上登陆 .NET 8 预览版 SDK。使 Visual Studio 利用最新功能。但是,不仅需要更改版本才能使

.NET 8 将于 11 月推出,Microsoft 推出了 C# 12.0 预览版,让我们大吃一惊。在第 7 次迭代中已经可以体验到以下出色的语言版本。

人们的兴奋已经越来越高了——C# 12.0 即将到来!这次会有什么新东西吗?听好了,我可能已经剧透了:是的!

如何启用新版本

看看 C#12.0 是值得的,也是有益的。许多新功能是期待已久的。不仅来自我的 POV。

因此,让我们在计算机上登陆 .NET 8 预览版 SDK。使 Visual Studio 利用最新功能。但是,不仅需要更改版本才能使用 C# 12 开发应用程序。您还需要通过将 LangVersion 切换为 来调整项目的 *.csproj 文件。net8.0preview

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <LangVersion>preview</LangVersion>
    </PropertyGroup>

</Project>

就这么简单,我想从一个控制台应用程序开始,让你引导。

最后,主要构造函数来了!

没什么好说的了,是吗?

主要构造函数授予您编写毁灭性的短构造函数。

var car = new Car("Ford", "Mustang");  
car.Print();  
  
public class Car(string brand, string model)  
{  
    public void Print() { Console.WriteLine($"{brand} {model}"); }  
    public string GlobalIdentifier => $"{brand} {model}";  
}

您可以直接在类型名称之后指定构造函数或其参数,而不是默认构造函数(它接受参数,然后将它们分配给正文中的字段)。

Microsoft通过将缩短的可能性应用于类,帮助了我们所有人。它以前已经对记录有效

new Temperature(60, 35),  
  
public readonly record struct Temperature(double HighTemp, double LowTemp)  
{  
    public double Mean => (HighTemp + LowTemp) / 2.0;  
}

所以这个例子很好地演示了它,这意味着作为回报:

  • 没有更多的任务
  • 不再有某种必要领域——精明!

这将极大地帮助您避免一些典型的样板代码错误。

但是,如果类有多个构造函数呢?

在这种情况下,C# 编译器会提示您同时调用主构造函数 use,从而重载它。this(...)

public class Car(string brand, string model)  
{  
    public Car()  
    { // Compile Error  
    }  
  
    public Car(  
 string releaseDate,  
 string brand,  
 string model)  
        : this(brand, model)  
    {  
  
    }  
}

那些已经处理过 TypeScript 的人会熟悉这种语法。

我立刻想到了两个问题:

主构造函数的参数是否也是属性?
可以使用可见性修饰符更改这些内容吗?

答案是:很遗憾,没有。

_主构造函数_的所有参数都是字段和私有参数。若要使参数作为属性可用,请显式编写它(比较上面的示例)。GlobalIdentifier

默认 lambda 参数,非常火爆!

请看以下代码片段。你觉得有什么不同?

var defaultStatement = (string? s = "Always Print this.")  
    => Console.WriteLine(s);  
  
defaultStatement();

默认 Lambda 参数的新功能在 asp.net Core 和 Minimal API 中非常方便。

如果 lambda 表达式可以是可选的,则可以通过多种方式调用该表达式,以便您构建 API 并使用可选参数。

我从没想过会这么容易——但现在它就像小菜一碟。

至于实现不是像往常一样的 Action 和 Func,而是使用可选签名创建一个匿名委托。

👮 拦截器——小心!

过去,这可以通过第三方工具完成。

我指的是修改现有代码的源生成器——由所谓的拦截器实现。在调用实际方法之前,可以插入带有源生成器的中间方法。

using System.Runtime.CompilerServices;
var anyClass = new AnyClass(); 
anyClass.MethodIWantToIncerept("My Default Message");

class AnyClass
{
    // this method is called in LINE 7
    public void MethodIWantToIncerept(string param)
    {
        Console.WriteLine($"Interceptable {param}");
    }
}

static class InterceptorClass
{
    // thanks to the interceptor, this method gets called INSTEAD
    [InterceptsLocation(@"pathToThisFile", line: 7, character: 10)]
    public static void InterceptorMethod(this AnyClass c, string param)
    {
        Console.WriteLine($"Intercepted Method with {param} ");
    }
}

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public sealed class InterceptsLocationAttribute(string filePath, int line, int character) : Attribute { }
}

若要在现有类型上创建扩展方法,需要在正确的命名空间 (System.Runtime.CompilerServices) 中创建属性。

您可以指定文件路径以及要截获的代码行/列。

因此,您可以在这里中断调用并添加代码以扩展它。手写这个是不切实际的,但有源生成器。

必需:将 <Features>InterceptorsPreview</Features> 添加到 *.csproj。

原因是它们是一个实验性功能。

别名 Any 类型启用 Weirdo 元组行为

当你每天都在编码上时,对编码完全中立是很困难的。但是你必须阅读Microsoft对Alias任何类型所做的事情

using System.IO;  
using Point = (int x, int y);  
Point simplePoint = new(13, 37);   
(int x, int y) unnessaryComplicatedPoint = new(23, 32);  
simplePoint = unnessaryComplicatedPoint;

现在,您可以使用 using 语句的别名来定义 by。

  • 例如,指简单的元组。Point
  • 即使该点只是一个元组,您也可以在文件中使用它。
  • 当您创建具有相同结构的元组时尤其明显,甚至类型赋值也是有效的。

如果使用 Tuples 是你的方式,你会喜欢这个快捷方式。您甚至可以将它用于不安全的类型:

using System.IO;   
using unsafe P = char*;   
unsafe void ShortCut() {   
    Pp = null;  
}
相关留言评论
昵称:
邮箱:
阅读排行