宣布推出 .NET 社区工具包 8.1!
我们很高兴地宣布 .NET Community Toolkit 8.1 版正式发布!这个新版本包括呼声很高的新功能、bug 修复和对 MVVM 工具包源代码生成器的大量性能改进,使开发人员在使用它们时的用户体验比以往更好!

就像在我们之前的版本中一样,我们非常感谢 Microsoft 使用该工具包的团队以及社区中的其他开发人员收到的所有反馈,这些反馈已经并将继续对我们如何设计所有新功能和改进并确定其优先级产生巨大影响。我们非常感谢每一位做出贡献并不断帮助 .NET Community Toolkit 变得更好的人!
.NET 社区工具包中有什么?
正如我们在之前的公告帖子中所做的那样,让我们首先简要回顾一下 .NET Community Toolkit 包含的内容。它由几个独立的库组成:
- CommunityToolkit.Common
- CommunityToolkit.Mvvm (又名“Microsoft MVVM Toolkit”)
- CommunityToolkit.Diagnostics
- CommunityToolkit.HighPerformance
这些库还广泛用于 Windows 附带的多个收件箱应用程序,例如 Microsoft Store 和照片应用程序!
有关 .NET Community Toolkit 历史的更多详细信息,请访问我们之前的8.0.0公告帖子的链接。
以下是 .NET Community Toolkit 新 8.1 版中包含的主要更改的部分。
自定义属性 [ObservableProperty]
正如我们在8.1.0预览版1公告博客文章中提到的,对于 MVVM 工具包源代码生成器,我们最需要的功能之一(请参阅#208、#217、#228)是支持对[ObservableProperty]使用自定义属性。有几个提议的设计来支持这一点,我们最终决定利用 C# 中的现有语法 “property”: 来让开发人员标记属性以传播到生成的属性。有几个优势:
- 它利用内置的 C# 语法,使该功能感觉“原生”并且不需要额外的属性
- 它解决了注解属性只能针对属性,不能针对字段的问题
也就是说,使用 MVVM Toolkit 8.1,现在支持以下场景:
[ObservableProperty]
[property: JsonPropertyName("responseName")]
[property: JsonRequired]
private string? _name;
这将在幕后生成以下属性:
[JsonPropertyName("responseName")]
[JsonRequired]
public string? Name
{ get => _name; set { if (!EqualityComparer<string?>.Default.Equals(_name, value)) { OnPropertyChanging("Name"); OnNameChanging(value); _name = value; OnPropertyChanged("Name"); OnNameChanged(value); } }
} partial void OnNameChanging(string? value);
partial void OnNameChanged(string? value);
可以看到生成的属性有我们指定的两个属性!这允许完全灵活地为生成的属性添加注释,同时使用内置的 C# 语法并且对该功能支持的属性类型没有限制。
注意:生成的代码略有不同,包括此处未显示的其他性能优化。
您可以在链接找到我们关于新源代码生成器的所有文档。
MVVM 工具包分析器
此版本的 MVVM 工具包也是第一个引入专用分析器的版本。它能够帮助开发人员以最佳方式使用 MVVM 工具包。也就是说,MVVM 工具包将不再只是针对使用错误的功能发出诊断(例如,以报错的方式),它现在还会显示改进代码和避免常见错误的建议!
第一个分析器涵盖了使用[ObservableProperty]属性时的一个常见错误。参照这个例子:
[ObservableProperty]
private string? name;[RelayCommand]
public async Task LoadUserAsync()
{User user = await _userService.FetchUserAsync();name = user.Name; // Whoops! Assigning to the field!
}
开发人员不小心分配给一个字段(而不是生成的属性),然后被卡在 UI 上。UI 上没有显示该更改,也没有明确说明为什么会这样,这一情景已经被多次提出。新的分析器将在这些情况下提供帮助,它将标记支持可观察属性的字段的所有赋值,并显示诊断建议引用生成的属性。你不会再收到莫名其妙的属性丢失的通知。
第二个新分析器旨在帮助减少使用 MVVM 工具包的应用程序中的二进制文件大小。正如我们在8.0.0 公告帖子中提到的,MVVM 工具包包含多个属性(例如[ObservableObject]),这些属性允许生成器将实现 INotifyPropertyChanged 和 INotifyPropertyChanging 接口所需的所有代码(也可选择使用其他帮助程序)注入现有类。
这仅适用于无法继承的情况:如果您不属于这种情况,您应该选择继承 ObservableObject,从而减小的二进制文件大小,因为编译器不必在每个过程中一遍又一遍地复制那些相同的助手类型。请参阅这个例子:
[ObservableObject]
public partial class MyViewModel
{[ObservableProperty]private string? name;
}
这里,MyViewModel 不是从任何类型继承而来,因此它应该继承 ObservableObject 而不是使用[ObservableObject]属性,以此改进二进制大小。新的分析器将标记所有与此类似的场景并建议改用继承。这将特别有助于初学者,他们可能不了解两种不同方法的细微差别并且可能不知道如何选择。在这些情况下,现在分析器可以提供帮助。
MVVM 工具包源代码生成器优化
正如我们提到的,这个新版本还包括对 MVVM 工具包的主要性能优化,以进一步改善开发人员的用户体验,尤其是优化了开发人员在处理非常大的解决方案时的体验。我们花了很多时间改进我们所有生成器的架构,并与 Roslyn 团队的工程师交谈,以确保我们正在尽可能地发挥它们的性能。
以下只是我们在这方面所做的一部分改进:
- 为 Roslyn 4.3 添加了多目标(#428,#462):如果支持,MVVM 工具包源代码生成器现在将使用 Roslyn 4.3 目标,这样他们就可以在主机支持的情况下选择加入一些更优化的 API。这一功能在引用 MVVM 工具包时会自动启用。
- 使用 ForAttributeWithMetadataName<T>(#436):我们将生成器切换到新的高级 Roslyn API 以匹配属性,这大大提高了生成器触发特定属性的性能。比如现在[ObservableProperty]就在用这个。
- 将诊断移入诊断分析器(#433,#434):我们将几乎所有诊断都移动到诊断分析器,这些诊断分析器在进程外运行并且独立于源生成器。这样能够显著减少键入时的overhead,因为所有诊断逻辑现在都在单独的进程中运行,并且不会降低 IntelliSense 的速度。
- 停止在增量提供程序中使用符号( #435 ):我们更新了所有增量提供程序以不再传播符号。这可以减少内存使用,因为传播符号会导致 Roslyn 不必要地根编译对象。
- 更多性能优化(#447、#460、#469、#487、#489):我们彻底检查了所有增量模型和增量管道,以显著提高性能并减少内存分配。
IObservable<T> 信使扩展
另一个功能需求,尤其是由那些在应用程序中大量使用响应式 API 开发人员提出,是寻求一种方法来桥接 MVVM 工具包中的功能。界面的新扩展 IObservable<T> extensions 现在支持此功能。它们可以按如下方式使用:
IObservable<MyMessage> observable = Messenger.CreateObservable<MyMessage>();
就像这样!此扩展将创建一个对象 IObservable<T> ,该对象可用于订阅消息并对其做出动态反应。还支持通过单独的重载指定不同的标记。这面这个示例展示了新 API 的端到端使用:
var token = Messenger .CreateObservable<MyMessage>() .Where(...) .Subscribe(m => Console.WriteLine($"Hello {m.Username}!"));
.NET 7和 C# 11支持
.NET Community Toolkit 工具包的新发布版本还将 .NET 7 TFM 添加到高性能包中,新版本中还包括一些变动,主要对新的 C# 11语言功能进行了改善,比如 ref fields 就是一个典型。
以下类型现在不再处于预览状态,以及更新使用了新的 ref 安全规则:
- Ref<T>
- ReadOnlyRef<T>
- NullableRef<T>
- ReadOnlyNullableRef<T>
下面这种场景可以使用这些规则:
public static bool TryGetElementRef(out NullableRef<T> reference)
{ // Logic here...
}
也就是说,使用 NullableRef<T> 类型规则可以有效地让方法具有 out ref T 参数, 而这在 C# 中是无法通过表达式做到的. 我们还计划扩展这些类型的 API 浅层面,从而允许这些类型通过使用 Unsafe 类型,提供一种易于使用的替代 GC-ref 算法的方法,这在视觉上也更类似于传统的指针算法。
此外,所有不在预览模式中的 ref struct 类型都已被更新,使用内部的 ref 字段实现更好的性能。这些类型包括:
- Span2D<T>
- ReadOnlySpan2D<T>
- RefEnumerable<T>
- ReadOnlyRefEnumerable<T>
- SpanEnumerable<T>
- ReadOnlySpanEnumerable<T>
其他变化
新版本中包含更多内容! 您可以在 GitHub release page 发布页面中查看完整的变更日志。
您可以在 GitHub repo 找到所有的源代码,也能在 MS Learn 上找到一些手写文档, 还能在 .NET API 浏览器网站中找到完整的 API 参考文档。如果您想为新版本的改善贡献自己的力量, 请随时提问题或联系我们,让我们知道您的体验!
如果您想了解有关 MVVM 工具包的更多信息,您还可以观看最近 .NET Conf 2022 中的视频。
新版本中有整套可用的 Toolkit-s 生态系统,其中有大量有用的 API 可用于构建 .NET 应用程序。祝您编码愉快!
相关文章:
宣布推出 .NET 社区工具包 8.1!
我们很高兴地宣布 .NET Community Toolkit 8.1 版正式发布!这个新版本包括呼声很高的新功能、bug 修复和对 MVVM 工具包源代码生成器的大量性能改进,使开发人员在使用它们时的用户体验比以往更好! 就像在我们之前的版本中一样,我…...
ChatGPT解开了我一直以来对自动化测试的疑惑
目录 前言 与ChatGPT的对话 什么是自动化测试,我该如何做到自动化测试,或者说需要借助什么工具可以做到自动化测试? 自动化测试如何确保数据的准确性 自动化测试是怎么去验证数据的 如何通过断言验证数据 自动化测试有哪些验证工具可以验证数据 总结 前言…...
十大经典排序算法(上)
目录 1.1冒泡排序 1. 算法步骤 3.什么时候最快 4. 什么时候最慢 5.代码实现 1.2选择排序 1. 算法步骤 2. 动图演示 3.代码实现 1.3 插入排序 1. 算法步骤 2. 动图演示 3. 算法实现 1.4 希尔排序 1. 算法步骤 2. 动图演示 3.代码实现 1.5 归并排序 1. 算法步骤 2…...
如何从 MySQL 读取 100w 数据进行处理
文章目录 场景常规查询流式查询MyBatis 流式查询接口非流式查询和流式查询区别游标查询场景 大数据量操作的场景大致如下: 1、 数据迁移; 2、 数据导出; 3、 批量处理数据; 在实际工作中当指定查询数据过大时,我们一般使用分页查询的方式一页一页的将数据放到内存处理。…...
【数据降维-第2篇】核主成分分析(KPCA)快速理解,及MATLAB实现
一篇介绍了PCA算法的快速理解和应用,本章讲一下KPCA。KPCA方法与PCA方法一样,是有着扎实的理论基础的,相关理论在论文上以及网络上可以找到大量的材料,所以这篇文章还是聚焦在方法的快速理解以及应用上,此外还会对同学…...
Python+ChatGPT实战之进行游戏运营数据分析
文章目录一、数据二、目标三、解决方案1. DAU2. 用户等级分布3. 付费率4. 收入情况5. 付费用户的ARPU最近ChatGPT蛮火的,今天试着让ta写了一篇数据分析实战案例,大家来评价一下!一、数据 您的团队已经为您提供了一些游戏数据,包括…...
Java每日一练(20230313)
目录 1. 字符串统计 ★ 2. 单词反转 ★★ 3. 俄罗斯套娃信封问题 ★★★ 🌟 每日一练刷题专栏 C/C 每日一练 专栏 Python 每日一练 专栏 Java 每日一练 专栏 1. 字符串统计 编写一个程序,对于输入的一段英语文本,可以统计&#…...
国内ChatGPT日趋成熟后,可以优先解决的几个日常小问题
现在ChatGPT的发展可谓如日中天,国内很多大的公司例如百度、京东等也开始拥抱新技术,推出自己的应用场景,但可以想象到的是,他们必定利用这个新技术在巩固自己的现有应用场景,比如某些客服,你都不用想&…...
业内人士真心话,软件测试是没有前途的,我慌了......
我在测试行业爬模滚打7年,从点点点的功能测试到现在成为高级测试,工资也翻了几倍。个人觉得,测试的前景并不差,只要自己肯努力。 我刚出来的时候是在鹅厂做外包的功能测试,天天点点点,很悠闲,点…...
哈佛与冯诺依曼结构
1. 下图是典型的冯诺依曼结构 2. CPU分为三部分:ALU运算单元,CU控制单元,寄存器组。 3. 分析51单片机为何能使用汇编进行编程 51指令集(Instruction Set)是单片机CPU能够执行的所有指令的集合。在编写51单片机程序时&a…...
传输安全HTTPS
为什么要有 HTTPS 为什么要有 HTTPS?简单的回答是:“因为 HTTP 不安全”。HTTP 怎么不安全呢? 通信的消息会被窃取,无法保证机密性(保密性):由于 HTTP 是 “明文” 传输,整个通信过…...
Docker--(六)--Docker资源限制
前言系统压力测试Cpu资源限制Mem资源限制IO 资源限制【扩展】 1.前言 在使用 Docker 运行容器时,一台主机上可能会运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制&#x…...
消息队列总结及案例
文章目录python内置队列先进先出的队列Queue分布式队列rabbitmqrocketmqredis list 队列python内置队列 标准库queue提供Queue队列、LifoQueue栈、PriorityQueue优先级队列用于单机的生产者、消费者缓冲队列; 生产者,生产消息的进程或线程;…...
通过WiFi连接adb调试
通过WiFi连接adb调试 解决 cannot connect to 192.168.1.136:5555: 由于目标计算机积极拒绝,无法连接。 (10061) 解决办法1 (Windows下cmd环境执行) 1.连接USB数据线,打开USB调试 使用windows的“运行”命令行方式:&a…...
【蓝桥杯-筑基篇】常用API 运用(1)
🍓系列专栏:蓝桥杯 🍉个人主页:个人主页 目录 🍍1.输入身份证,判断性别🍍 🍍2.输入英语句子,统计单词个数🍍 🥝3.加密解密🥝 🌎4.相邻重复子串…...
想要成为高级网络工程师,只需要具备这几点
首先,成为高级网络工程师的目的,就是为了搞钱。高级网络工程师肯定是不缺钱的,但成为高级网络工程师你一定要具备以下几点:第一 心态作为一个高级网工,首先你必须情绪要稳定,在碰到重大故障的时候不慌&…...
c++ 每日十问3-处理数据
1.为什么 C有多种整型? 解析: C语言中包含多种整数类型,主要包括 short、int、long 和 long long 这4种,每一种还分别包含有符号类型和无符号类型(unsigned)。此外,char 类型也可以看作一种小整数类型。C语言中这些整数类型的主要区别在于存…...
【MySQL】实验一 数据定义
目录 1. 表定义:创建工程项目表 2. 表定义:创建供应商表 3. 表定义:创建供应情况表 4. 表定义:创建零件表 5. 表定义:创建student表 6. 表定义:创建course表 7. 表定义:创建sc表 8.…...
17.电话号码的字母组合(深度递归遍历解决经典老题)
前文C深度递归遍历解决"电话号码的字母组合问题",本题考察的比较全面,考察到vector的使用,深度遍历以及递归的熟练度,希望能对铁子们有所帮助一,题目链接:https://leetcode.cn/problems/letter-c…...
Python 基础教程【1】:Python介绍、变量和数据类型、输入输出、运算符
本文已收录于专栏🌻《Python 基础》文章目录1、Python 介绍2、变量和数据类型2.1 注释的使用2.2 变量以及数据类型2.2.1 什么是变量?2.2.2 怎么给变量起名?2.2.3 变量的类型🎨 整数 int🎨 浮点数(小数&…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
