.NET Conf 2022 在昨晚(11月8日) 11 点 正式开始了,为期三天的会议(11月8-10日), 围绕 .NET 7 展开。 相信各位小伙伴都已经开始安装 .NET 7 正式版本还有以及相关的开发工具。这次 .NET 7 围绕传统的 C# , ASP.NET Core , Blazor , .NET MAUI , 云原生等内容进行了更新。下面归类总结一下我比较关心的更新内容,希望能给各位小伙伴一个快速的介绍。
泛型是编程语言的一种风格。让程序员在强类型程序设计语言中编写代码使用一些以后才指定的类型。C# 在 2.0 开始支持泛型,C# 版本更替时不断对泛型的支持进行了增强和补充。在 C# 11 中,增加了泛型属性。
这是一段 ASP.NET 的代码,每个字段都有一些要求属性,如必填的字段,限制范围,以及对应的类型等
public class Movie
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Title { get; set; } = null!;
[ClassicMovie(1960)]
[DataType(DataType.Date)]
[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }
[Required]
[StringLength(1000)]
public string Description { get; set; } = null!;
[Range(0, 999.99)]
public decimal Price { get; set; }
public Genre Genre { get; set; }
public bool Preorder { get; set; }
}
你可以通过 System.Attribute 派生出不同的属性。
在 C# 11 之前你也可以去做泛型属性的定义,通过 System.Type 在自定义属性类中作为构造函数的参数进行传递
[AttributeUsage(AttributeTargets.Class)]
public class Conditions: Attribute
{
public Conditions(Type t)
{
ParamType = t;
}
public Type ParamType { get; }
}
实现
[Conditions(typeof(string))]
public class Player
{
public string Number { get; set; }
public string Name { get; set; }
}
而 C# 11 增加了对泛型属性的支持。 直接定义一个泛型类,不用再将 System.Type 作为参数传递给构造函数。 而且可以有一个或者多个类型作为参数, 而且类型安全性也增加了
[AttributeUsage(AttributeTargets.Class)]
public class Conditions: Attribute
where T : class
{
public Conditions()
{
}
public T ParamType { get; }
}
[Conditions()]
public class Player
{
public string Number { get; set; }
public string Name { get; set; }
}
因为有了泛型类的加持,您可以在类型参数上灵活添加不同的条件约束。
在定义字符串时,我们往往夹杂着很多的符号,换行还有空格,但过往这些都需要增加转移字符,但现在通过原始字符串可以让字符串定义更为简单,也更容易给人接受
string longMessage = """
This is a long message.
It has several lines.
Some are indented
more than others.
Some should start at the first column.
Some have "quoted text" in them.
""";
从 C# 11 开始,可以将数组或列表与模式的序列进行匹配,如以下示例所示:
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers is [1, 2, 3]); // True
Console.WriteLine(numbers is [1, 2, 4]); // False
Console.WriteLine(numbers is [1, 2, 3, 4]); // False
Console.WriteLine(numbers is [0 or 1, <= 2, >= 3]); // True
这个虽然看似是语法糖,但是对于一些数据处理的场景时非常有用的,例如 CSV或者事固定长度的文件数。
以前,字符串插值 {text} 的文本只允许一行。 现在在 C# 11 中,此文本可以允许多行。$ 特殊字符将字符串文本标识为内插字符串 。 内插字符串是可能包含内插表达式的字符串文本 。 将内插字符串解析为结果字符串时,带有内插表达式的项会替换为表达式结果的字符串表示形式。
string message = $"The usage policy for {safetyScore} is {
safetyScore switch
{
> 90 => "Unlimited usage",
> 80 => "General usage, with daily safety check",
> 70 => "Issues must be addressed within 1 week",
> 50 => "Issues must be addressed within 1 day",
_ => "Issues must be addressed before continued use",
}
}";
委托用于将方法作为参数传递给其他方法。 最常见的委托是 Action、Func 和 EventHandler。 您可以使用 lambda 表达式来提供委托,也可以使用方法组。 您还可以将委托缓存到一个字段中,并在需要时重用该实例。
例如这个就是我们经常使用的定义
void ActionDelegetDemo(Func action) { }
string GetPlayer() => "";
在 C# 11 之前 我们通过方法组进行委托的调用,如
ActionDelegetDemo(GetPlayer);
ActionDelegetDemo(new Func(GetPlayer));
在 C# 11 后,你可以通过没有闭包的 Lamda / 方法中去实现
ActionDelegetDemo(() => GetPlayer());
也可以通过手动委托的方式来实现
static readonly Func Instance = new Func(GetPlayer);
ActionDelegetDemo(Instance);
C# 11 和 .NET 7 包括接口中的静态抽象成员。 它可定义重载运算符或其他静态成员的接口。 使用静态成员定义接口后,可使用这些接口作为约束来创建使用运算符或其他静态方法的泛型类型。通过将 static 和 abstract 修饰符添加到不提供实现的任何静态成员,如
public interface IGetNext where T : IGetNext
{
static abstract T operator ++(T other);
}
这个功能在范型处理是非常方便的,我们可以在接口中包含静态抽象成员,然后我们可以对泛型方法指定一个约束,即类型参数应该从这个特定的接口派生。 一旦完成,泛型方法就可以轻松调用静态方法。
如果你是传统的 Xamarin 开发者,你肯定对 AOT 技术不陌生,因为有 Mono AOT , 而针对客户端场景和服务器场景也有 ReadyToRun。Native AOT 技术可以将 .NET 应用程序编译成本机可执行文件 ,也还可以生成独立的动态或静态库从而给其他编程语言调用。 Native AOT 应用程序启动速度非常快,而且对于内存的使用也是非常小的。你可以在没有 .NET 运行时的设备上直接运行 Native AOT 的应用。 Native AOT不使用 JIT 编译器,所以它可以在 JIT 受限制的环境中运行。 它可以在 Arm64 / x64 的环境下运行。 这个或者让大家想到了 Rust ,也想到了 Go。现阶段,.NET 7 的 Native AOT 非常受限只有控制台和一些库文件支持。但这是第一步,希望各位小伙伴也能尽量去尝试。
如果你要创建一个 Native AOT 的应用,需要在 csproj 文件中添加:
true
你也可以针对 Linux 或者 Windows arm / x64 编译 Native AOT 应用,例如
dotnet publish -r linux-arm64 -c Release
注意在 Ubuntu 环境下 , 你需要添加以下的一些库 clang zlib1g-dev
sudo apt-get install clang zlib1g-dev
现在 Native AOT 还是比较受限,我更期待能支持一下 MAUI , 这样是不是路更广。还有我使用 Native AOT 编译出来的应用过大,是否需要考虑压缩一下呢 ? 我能理解它是增量的,但是一个 HelloWorld 应用也大得有点夸张了。希望它能越来越好。
.NET MAUI 是一道坎,或者很多小伙伴希望它能做更多。有人会希望性能有所提升,有人希望能在 Linux 上得到支持,也有人希望 IDE 能够完善一点。 我一直和 .NET MAUI 的团队保持沟通,也希望尽快能实现各位小伙伴的愿望。 在 .NET 7 中,.NET MAUI 在桌面应用的支持有了很多的改善。在手势,在桌面菜单,以及对鼠标支持,右键菜单,窗体缩放都有很好的支持。或者期望更多了。 这不是最好的更新,但是这是更稳定的跨平台应用开发。我们在期待更大更新的时候,更应该开始着手投入到 .NET MAUI 的应用开发中来了,
开发体验上 .NET MAUI 已经支持 iOS 16 和 Android 13 了, 这也解决了 Xcode 14 不兼容的问题。与时俱进是我喜欢 .NET MAUI 的原因。还有 Hot Reload 也有了一个进化,支持 .NET for iOS 和 .NET for Android 以及 Blazor WebAssembly 了。
说完 .NET MAUI , 说到端应用不能不提及 Blazor . 这几年 Blazor 的应用持续攀升,这也得益于一个好的性能以及 WebAssembly 技术 的发展。我个人很喜欢 WebAssembly。 .NET 7 为基于 JavaScript 的应用中的 WebAssembly 上运行 .NET 提供了改进的支持,包括丰富的 JavaScript 互操作机制。 .NET 7 中的 WebAssembly 支持是基于 Blazor WebAssembly 应用程序,但也可以独立于 Blazor 使用。 现有的 JavaScript 应用程序可以使用 .NET 7 中扩展的 WebAssembly 支持来重用 JavaScript 中的 .NET 库或构建全新的基于 .NET 的应用。 Blazor WebAssembly 应用程序还可以使用新的 JavaScript 互操作机制来优化与 JavaScript 和 Web 平台的交互。
各位小伙伴在安装好 .NET 7 后可以在命令行中通过 workload 添加 wasm 的支持
dotnet workload install wasm-tools
dotnet workload install wasm-experimental
添加完成后,你就可以通过创建你的 wasm 应用
dotnet new wasmbrowser
还有也有了 AOT 的支持,通过 AOT 你可以提升运行速度,通过修改 csproj 文件就可以获取 AOT 支持
net7.0
main.js
Exe
enable
true
+ true
+ full
+ true
发布也非常简单
dotnet publish -c Release
而且还支持在本地托管发布应用
dotnet tool install --global dotnet-serve
dotnet serve --mime .wasm=application/wasm --mime .js=text/javascript --mime .json=application/json --directory bin\Release\net7.0\browser-wasm\AppBundle\
用 .NET 做机器学习,很多人会打一个问号。但微软就是要把 .NET 可以做机器学习的问号变成了叹号。 ML.NET 在 1.5 后,特别是 ML.NET CLI 已经非常好用,特别是 AutoML 这块。 在 ML.NET 2.0 对于自然语言这块的处理都有非常大的改进。这得益于 TorchSharp 的改进。或者是受 TensorFlow.NET 的影响, 自家支持的 TorchSharp 也有了很大的进步。
自然语言是非常常见的问题, ML.NET 新增加了文本分类的 API ,让开发者通过少量的代码就可以完成文本分类,情感分析,以及摘要提取等工作。具体的 API 封装如下
你可以理解为 ML.NET 帮你完成了 80% 的工作,包括最复杂的自然语言算法构建等工作,你需要做的就是提供数据, 和相关 API 的调用。 这是官方的一个示例
using Microsoft.ML;
using Microsoft.ML.TorchSharp;
var mlContext = new MLContext();
var reviews = new[]
{
new {Text = "This is a bad steak", Sentiment = "Negative"},
new {Text = "I really like this restaurant", Sentiment = "Positive"}
};
var reviewsDV = mlContext.Data.LoadFromEnumerable(reviews);
var pipeline =
mlContext.Transforms.Conversion.MapValueToKey("Label", "Sentiment")
.Append(mlContext.MulticlassClassification.Trainers.TextClassification(numberOfClasses: 2, sentence1ColumnName: "Text"))
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
// Train the model
var model = pipeline.Fit(reviewsDV);
我们可以看到非常简洁,并不需要很多的机器学习/深度学习知识,这也让更多 .NET 开发者能更快使用 ML.NET 到项目中来。
.NET 7 在 .NET 6 基础上做了加一的操作,让 .NET 朝着更好的自己又迈进了一步。对于众多 .NET 开发者而言,我们会继续拥抱 .NET , 当然也希望有更多的人加入到 .NET 的开发大家庭中来。 .NET 7 并不是终点,每次版本的发布都是一个重新的起点。希望 .NET 越来越好。
ps : 这次 .NET Conf 2022 不仅有 .NET 7 , 官网也更新了,更加直观好用,大家快快上去看看
最后希望大家记得支持我在 11月 10 日 北京时间下午 13:30 - 14:00 关于 .NET 做深度学习的课程
相关文档