.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
请看以下代码片段。你觉得有什么不同?
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。
当你每天都在编码上时,对编码完全中立是很困难的。但是你必须阅读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。
如果使用 Tuples 是你的方式,你会喜欢这个快捷方式。您甚至可以将它用于不安全的类型:
using System.IO;
using unsafe P = char*;
unsafe void ShortCut() {
Pp = null;
}