前言

之前写过 6.0, 7.0, 8.0, 9.0 总结.

10.0 也是有些好东西哦, 尤其是 pattern matching 的完善, 差不多是时候可以重构 if else switch 的写法了.

主要参考

C# 10: New features and examples that are not in C# 9 (.NET 6)

Every feature added in C# 10 with examples

The evolution of Pattern Matching in C# (from version 6 to 10) <-- pattern matching 重点看这视频

Global using

只要在其中 1 个 .cs file 写 global using, 就等于在所有 .cs file 写了 using

before, 必须 2 个 file 都写 using

after, 只要其中一个写就可以了

虽然我们提倡各个 file 应该要各种负责, 按需 using, 但是把一些常用的放一起也是一种好的管理方式.

不错用

namespace 省略 bracket

这个有点像 using 省略 bracket 一样

before

after

注: namespace 结尾要加 semicolon 哦.

must use

Constant + Interpolated String

before

会 error

after

没 error 了

const string 和 js 的 const 一样, 就是不能改.

定义匿名函数返回类型

var method = string? () => null;

string? 就是函数的返回类型, 厉害吧.

解构 + 声明 + 赋值

var method = () => ("a", 11);
int number;
(var value, number) = method();

这个比 Typescript 还厉害. var 声明 value, 同时赋值 number

Record 总结

Intro to Records in C# 9 - How To Use Records And When To Use Them

Record Structs

Record Structs

首先要搞懂 class 和 struct, 看这篇,

最简单的理解是 class 是引用类型, struct 是值类型

它们都是 key-value 结构.

9.0 开始 C# 多了一个 record, 它也是 key-value 结构, 所以又多一个傻傻分不清楚了.

依据上面的视频, record 是引用类型, 但是它又是 immutable 的 (内容不可以改)

熟悉函数式的人应该对 immuatable 的好处有共鸣啦. 要不你用过 React, Angular 也应该听过它.

简单理解就是它把 class 改装成了一种不可以改的对象.

由于它们太像了, 10.0 干脆做了个 mix record class, record struct, Oh Yeah 更傻傻分不清楚了.

总之记得:

class, record 是引用类型, struct 是值类型 (提醒: object.Equals(record) 它会对比值而不是 reference, 这个比较特别, 要留意哦)

record, record class, record struct 都支持 with 语法, 就是可以 clone 赋值.

class 通过 property set init, Deconstruct 也可以做到类似 record 的感觉. 但它不能用 with 语法来 clone 赋值, record class 才可以用 with.

record class 如果没有做 set init 它是可以改值的哦. 它只是让 class 可以 with 而已.

最后我目前依然没有用到 record 或者 immuatable 概念, 所以以后用到了才分享多一点.

record 长这样

定义

public record ImageDimension(int Width, int Height);

创建 + 赋值 + 解构

var dimension = new ImageDimension(100, 200); // 创建
var newDimension = dimension with { Height = 50 }; // 赋值
var (width, height) = dimension; // 解构

解构的顺序就是初始化 parameter 的顺序.

用 record class 来写长这样

public record class ImageDimension
{
public int Width { get; init; }
public int Height { get; init; }
internal void Deconstruct(out int width, out int height) => (width, height) = (Width, Height);
} var dimension = new ImageDimension
{
Width = 100,
Height = 70
};
dimension.Width = 5; // erorr 编译不通过
var newDimension = dimension with { Height = 30 };
var (width, height) = dimension;

加个 construct 调用会更像. setter init 和 Deconstruct 本来就是 class 的功能. record 只是让它支持 with 而已.

record class overload constructor

遇到一个 error, 不清楚什么原因, 先记入在这里.

A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object. [TestRImage]csharp(CS8868)

引发的原因是 record class + overload constructor + parameter is class object + calling this

目前没空检查. 解决方法就是不要 call this.

Pattern Matching 总结

Pattern matching 是一种条件判断的表达方式. 它的目的是提升可读性, 减少没必要的重复语句.

凡是用到条件判断的地方都可以用. 比如 if else, switch, 甚至 catch

它的关键就是对 is 提升了很多, 较早的版本, is 只能用来判断类型而已. 现在是整个 pattern matching 的开头关键字丫.

is null, is not null

var person = new Person();
if (person is Person) { }; // 5.0
if (person is null) { }; // 7.0
if (person is not null) { }; // 9.0

一路走来也是不容易啊, 当 9.0 才有 is not null.

is 当 ==, >, >=, <, <= 用

var name = "dada";
var age = 1;
if (name is "dada") { }
if (age is >= 10) { }

and 和 or

var name = "dada";
var age = 1;
if (name is "dada" or "tata") { }
if (age >= 10 && age <= 100) { } // before
if (age is >= 10 and <= 100) { } // after

before 需要重复 age, after 少了重复, 也把符号变成语句, 这样就更好读了.

is 配上 and

var value = "abc";
if (value is not "abc" and not "xyz")
{ }

如果想判断 value "不是 abc" 同时 "不是 xyz" 写法是上面这样. 2 个 not, 而不是

value is not "abc" and "xyz", 这句的意思是 value 是 "不是 abc" 同时 "是 xyz"

对属性进行判断

if (animal is { Name: "dada" or "tata", Age: > 10 or < 18 }) { }

再加一个类型判断也可以

if (animal is Dog { Name: "dada" or "tata", Age: > 10 or < 18 }) { }

子属下也可以直接 dot 出来

if (animal is Dog { child.ChildProp: "dada" or "tata" }) { }

双值判断

if ((name, age) is ("dada" or "tata", > 10 and < 20)) { }

skip 掉第一个判断 (switch 的时候比较会用到)

if ((name, age) is (_, > 10 and < 20)) { }

用到 switch case 上

上面的判断也适用于 switch case

switch case return

var result = animal switch
{
{ Name: "dada" or "tata", Age: > 10 and < 100 } => "value1",
_ => "default"
};

注: body 只可以是 expression, 不可以是 statement.

switch case action

switch (animal)
{
case { Name: "dada" or "tata", Age: > 10 and < 20 }:
// do somthing
break;
default:
// defualt
break;
};

switch case action 爽值判断

switch (name, age)
{
case ("dada" or "tata", > 10 and < 20):
// do something
break;
default:
// defualt
break;
}

Pattern matching 目前已经比较成熟了, 但我相信它还有不足够的地方,而且也不是 100% 场景都合适.

但我觉得, 已经是时候可以开始尝试了.

Linq 提升

虽然这个不算 C# 语法, 但是我也没有地方写了, 干脆记入这里吧.

参考:

Bite-Size .NET 6 - UnionBy, IntersectBy, ExceptBy, and DistinctBy

Bite-Size .NET 6 - MaxBy() and MinBy() in LINQ

大同小异的功能, 我解释一个就好了呗.

IntersectBy

var dtoProperties = dto.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
var entityProperties = entity.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();

2 个 list, 我要找出相同 property.name 的

var intersectProperties1 = dtoProperties.Intersect(intersectProperties, comparer);

从前需要写一个 comparer. 超级不友好.

有时宁愿牺牲表达, 用 Where 来替代.

var intersectProperties = dtoProperties.Where(dtoProperty => entityProperties.Any(entityProperty => dtoProperty.Name == entityProperty.Name)).ToList();

现在不用烦, IntersectBy 搞定.

var intersectProperties2 = dtoProperties.IntersectBy(entityProperties.Select(p => p.Name), p => p.Name).ToList();

C# – 10.0的更多相关文章

  1. CentOS7 编译安装 nginx-1.10.0

    对于NGINX 支持epoll模型 epoll模型的优点 定义: epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著的 ...

  2. Could not load file or assembly 'Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its de

    页面加载时出现这个错误: Could not load file or assembly 'Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Cul ...

  3. Centos7下安装mono3.10.0

    mono 3.10.0 正式发布:性能进一步改进,以前已经写过一篇  Centos 7.0 安装Mono 3.4 和Jexus 5.6.下面我们在CentOS 7上通过源码安装Mono 3.10, 需 ...

  4. mono 3.10.0 正式发布:性能进一步改进

    Mono是Xamarin资助的一个项目,是微软的.NET框架的开源实现.它使得使用C#.F#和其他.NET语言进行跨平台开发成为可能.Xamarin在Mono之上构建了跨平台开发工具以及像Xamari ...

  5. VMware Workstation 10.0 正式版官方简体中文下载(附序列号)

    虚拟机界数一数二的王者软件VMWare Workstation 今日推出了最新的VMware Workstation 10.0 版本.该版本最大的更新是加入了简体中文语言,这意味着未来神马汉化包.中文 ...

  6. DPA 9.1.85 升级到DPA 10.0.352流程

    SolarWinds DPA的升级其实是一件非常简单的事情,这里介绍一下从DPA 9.1.95升级到 DPA 10.0.352版本的流程.为什么要升级呢? DPA给用户发的邮件已经写的非常清楚了(如下 ...

  7. C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0

    C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0

  8. kafka0.9.0及0.10.0配置属性

    问题导读1.borker包含哪些属性?2.Producer包含哪些属性?3.Consumer如何配置?borker(0.9.0及0.10.0)配置Kafka日志本身是由多个日志段组成(log segm ...

  9. 又一次的Microsoft Visual C++ 10.0 is required (Unable to find vcvarsall.bat)

    ~~~~~~~~~~~My problem is here~~~~~~~~~~~~~~~~~~~~~~ Error: Microsoft visual C++ 10.0 is required (un ...

  10. 在VisualStudio2012环境下安装ArcEngine 10.0

    因为ArcEngine10.0默认对应的开发工具为VS2010,在安装了VS2012的情况下安装ArcEngine10.0(注意:我自己的环境为VS2012和ArcEngine10.0,对于其他版本在 ...

随机推荐

  1. [oeasy]python0075_删除变量_del_delete_variable

    删除变量 回忆上次内容 上次我们研究了字节序 字节序有两种   符号 英文名称 中文名称 < little-endian 小字节序 > big-endian 大字节序 字节序 用来 明确 ...

  2. [oeasy]python0123_中文字符_文字编码_gb2312_激光照排技术_王选

    中文编码GB2312 回忆上次内容 上次回顾了 日韩各有 编码格式 日本 有假名 五十音 一字节 可以勉强放下   有日本汉字 字符数量超过20000+     韩国 有谚文 数量超过500 一个字节 ...

  3. [oeasy]python0072_自定义小动物变色_cowsay_color_boxes_asciiart

    修改颜色 回忆上次内容 上次搞的是 颜色 前景颜色 总共有 7 种基本色 还有什么 好玩的 么? 可以 给小动物 上色 吗? 配合 先将cowsay结果 输出重定向 sudo apt install ...

  4. 【译】使 Visual Studio 更加可视化

    任何 Web.桌面或移动开发人员都经常使用图像.你可以从 C#.HTML.XAML.CSS.C++.VB.TypeScript 甚至代码注释中引用它们.有些图像是本地的,有些存在于线上或网络共享中,而 ...

  5. gitbook 入门教程之比较代码块差异 diff 插件

    在 markdown 文档中显示代码之间的差异的 Gitbook 插件 English | 中文 主页 Github : https://snowdreams1006.github.io/gitboo ...

  6. go 环境搭建

    下载go 编辑器 https://www.jetbrains.com.cn/go/ 激活工具可以留言,我看到就回复.(保存在阿里云盘) 编辑器配置 GOPROXY=https://goproxy.cn ...

  7. Windows下搭建Vue脚手架CLI

    Vue CLI的使用依赖Node.js,先按照Node.js环境. //安装环境C:\Users\16779>npm install --global vue-cli npm WARN depr ...

  8. golang对遍历目录操作的优化

    一转眼go1.23都快发布了,时间过得真快. 不过今天我们把时间倒流回三年半之前,来关注一个在go1.16引入的关于处理目录时的优化. 对于go1.16的新变化,大家印象最深的可能是io包的大规模重构 ...

  9. Jmeter函数助手35-property

    property函数用于获取jmeter属性值. 属性名称:填入jmeter的属性名称 存储结果的变量名(可选) 默认值:缺省值,当获取属性值为空时则返回该值 1.查看jmeter全局属性,测试计划右 ...

  10. 【RabbitMQ】10 深入部分P3 死信队列(交换机)

    1.死信交换机 说是死信队列,是因为RabbitMQ和其他中间件产品不一样 有交换机的概念和这个东西存在,别的产品只有队列一说 DeadLetterExchange 消息成为DeadMessage之后 ...