前言

C# 这几年改了好几个版本, 多了许多语法糖,还带有 JavaScript / TypeScript 的味道了.

我觉得随着 blazor 的发展 (想取代前端开发 ?) 那 C# 必然需要更多类似 TS 的语法.

这里记入一下常用到的.

参考:

List of All New Features in C# 6.0: Part 1

C# version 7.0

What's new in C# 8.0

What's new in C# 9.0

1. using static (6.0)

一般上 using 都是配上一个 namespace, 然后下面调用时写 ClassName.StaticMethod();

有了 using static, 我们可以直接写 using static Namespace.ClassName 然后直接在下面调用 StaticMethod() 省去了每次写 ClassName.

感觉没有什么鸟用啦.

2. init property value  (6.0, 7.0)

public int age { get; set; } = 5;

以前 init value 只能写在 construtor 里.

must use

3. Dictionary 字典 int value (6.0)

var before = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" },
};
var after = new Dictionary<string, string>
{
["key1"] = "value1",
["key2"] = "value2"
};

新的写法更像 key-value pair 了.

must use

4. nameof (6.0)

var stringValue = nameof(IndexModel.OnGet); // "OnGet"

取代了原本直接写 string "OnGet", 写 string 最大的问题就是不容易批量换.

must use

5. catch when (6.0)

try
{ }
catch (Exception ex) when (ex.Message.Length > 10)
{
throw;
}
catch (Exception ex) when (ex.Message.Length > 3)
{
throw;
}

以前 catch 只能依据类型进入到不同的 catch, 现在可以多加一些表达式. 易读性提高了.

must use

6. Null-Conditional Operator (6.0)

Object?.Property, or Object?.Method() 当 object 是 null 的时候直接返回 null,

遇到 Func 和 Action 的时候要这样写哦

must use.

7. expression method (6.0)

public string getValue(string value) => "dada" + value;

以前一定要写 return, 类似这种 () { return ".."; }. 但 lambda 也不总是比 return 更好看哦.

大部分情况好用

8.String interpolation (6.0)

参考: $ - string interpolation (C# reference)

var x = $"{language}-some value";

$ 声明这个 string 是 interpolation, 花括弧 {} 表示要嵌套进去的 variable. 这个和 JavaScript 的 `hi, ${value}` 差不多.

另外需要注意的是, 当遇到特殊符号的处理.

当遇到 " 时, 需要添加反斜杠 \"

当遇到 {} 时, 需要写 double

当遇到 \ 时, 需要写 double

还有, 它不能 new line

可以通过 string literal 来解决, 添加 @ 在前面.

然而, 添加 @ 同时会改变一些规则

当遇到 " 时, 不再使用反斜杠, 取而代之的是用 double

当遇到 \ 时, 则不再需要用 double 了.

C# – 11.0 还有一些加强哦.

另外, 里面不需要写 .ToString, 比如

var number = 1.65m;
var value1 = $"{number}"; // 1.65
var value2 = $"{number.ToString()}"; // 1.65

value1, value2 是等价的.

如果遇到要传参数可以加分号

var date = DateTime.Now;
var value = $"{date:dd-MMM-yyyy}"; // 11-Jun-2023

must use

9. Tuples & Deconstruct (7.0)

参考: Docs – Tuples

C# 一直没有类似 JS 的 array / object. 一旦你用 array / object 就没有类型了. 后来 TS 有了 Tuples, C# 7.0 后也有了.

我一般把它当 TS 来用, 可以快速的定义一些匿名对象或者 array 等等. 不需要什么都搞 class. 灵活度大大提升了.

(string, DateTime, int) array = ("str", DateTime.Now, 3);
var str = array.Item1;
(string name, int age) obj = (name: "str", age: 11);
var name = obj.name; var array2 = ("str1", "str2");
var value = array2.Item1; // string?

需要注意, 如果用 var 的话, 智能匹配出来的结果是 nullable string 哦, 建议声明类型来使用 Tuples 不要用 var

注: 方法也是可以直接返回 Tuples 的, C# 的 Tuples 一律用圆括弧 ()

Tuples must use

如果已经是 class object 了, 就不能像 TS 那样直接解构了. 这点有待加强.

public class Point
{
public Point(double x, double y)
=> (X, Y) = (x, y); public double X { get; }
public double Y { get; } public void Deconstruct(out double x, out double y) =>
(x, y) = (X, Y);
} public void OnGet(string? language, string? amp)
{
var p = new Point(3.14, 2.71);
var (x, y) = p;
var (whateverName, _) = p; // variable 名字可以随便取, 它依赖顺序, underscore 代表 skip
var value1 = 5;
(value1, var y) = p; // 也可以给 existing variable 赋值
}

需要特别声明一个 Deconstruct 的方法. 对象才能被解构.

Deconstruct 挺麻烦, 比起 JS 差远了, 不好用.

10. Pattern matching (7.0)

C# 一直在优化 pattern matching 语法, 以前写 if else 有时真的非常难读懂.

is + 变量

object obj = DateTime.Now;
if (obj is DateTime date)
{
((DateTime)(obj)).AddDays(10);
date.AddDays(10);
}

声明一个变量在 is 条件判断后面就可以以当下的类型替代原本的 obj 来调用了. 类似 ts

配合 swtich 也是可以用

object obj = 1;
switch (obj)
{
case int number when number > 0:
// do something
break;
}

对了, case when 和之前提到的 catch when 是类似的, 也和 sql 语法 case when 一样哦.

must use

11. Local functions (7.0) & static local function (8.0)

写 C# 经常遇到这种情况,就是你的一个方法里面需要重复一些代码执行, 一般的做法就是开一个私有 method 封装.

但是这样动作可能有点大. 因为只是某个方法内部需要复用而已丫. 于是 local function 就很适合这种场景了.

跟 js 很类似.

string getValue(string value) => "value" + value;
var x = getValue("dada");

上面我刻意写成了没有 return. 刚才介绍过的功能.

must use

8.0 之后还可以加上 static, 我个人喜欢用 static 多一些, 毕竟 local function 偏函数式概念了, 所以尽量做成纯函数.

12. 直接声明 default 变量 (7.0)

int number = default;

之前是需要调用的 default(int) 省去了重复, 适合用于 parameter 初始值哦

must use

13. number 可是下划线来分开 0 (7.0)

1,000,000 这个是 100万

在 C# int value =  1_000_000 可以这样写

must use

14 out variable (7.0)

if (int.TryParse("5", out var result))
Console.WriteLine(result);
else
Console.WriteLine("Could not parse input");

以前智能把变量声明在外面, 非常不友好.

must use

15. getter setter expression (7.0)

must use

private int myVar;
public int MyProperty
{
// get { return myVar; }
// set { myVar = value; }
get => myVar;
set => myVar = value;
}

注释的是之前的写法. 新的写法更好阅读了.

must use

16. Switch expressions (8.0)

当我们想写一堆 if else 然后返回一个值的时候, 这个超好用的.

var value = "dada";
var final = value switch
{
"kk" => "value 1",
"dada" => "value 2",
_ => throw new NotImplementedException()
};

must use

17. switch property patterns tuple patterns (8.0)

我们知道 switch 可以匹配类似, 现在还可以匹配 property 和 tuple

var person = new Person();
var final = person switch
{
{ Name: "dada", Age: 3 } => "w",
_ => throw new NotImplementedException(),
};
var tuple = ("a", "b");
var final1 = tuple switch
{
("a", "b") => "dada",
_ => throw new NotImplementedException()
};

匹配只能是最简单的等于 =, 这个有点弱. 如果可以写多点判断逻辑会更好用. 并没有完全能替代 if else, 只是某些情况适用.

不错用

18. using declarations (8.0)

using var file = new System.IO.StreamWriter("WriteLines2.txt");
file.Flush();

省略掉了花括弧, 它的 scope 就是跟着当前的 block 跑. 如果要提早 displose  的话, 可以用回之前花括弧写法.

must use

19. Nullable reference types (8.0)

string? abc, Person? person

从前对象, string 都是 nullable. 在编写代码的时候没有智能提醒. 现在有了这个我们就可以表示是不是 nullable 了.

must use

20. Indices and ranges (8.0)

参考: Indices and ranges

注意 ^1 是最后一个, ^0 是拿 length

让拿 range 或者 substring 都可以下面这样写

var a = new string[] { "1", "2", "3", "4" };
var t = a[0..2]; // [1, 2]
var t1 = a[..2]; // [1, 2] 前面没写就是从 0 start
var t2 = a[0..]; // [1, 2, 3, 4] // 后面没写就是^0
var t3 = a[0..^0]; // [1, 2, 3, 4] // 后面没写就是^0

第一个参数是开始的位置, 会拿到. 第二个参数是结尾的位置 (不是拿 length 哦, 是位置,位置), 不会拿到. 和 js 的逻辑是一样的.

如果超出范围只是拿不到, 不会报错. 当然你不要去写 negetive 啦.

注: List<T> 支持 indices 但不支持 range...即使可以这样 myList[^2] 但不可以 myList[0..1]

解决方法是用 .Take(0..1)

must use

21. Null-coalescing assignment (8.0)

通过 ?? 来给 null 复值. 取代了 ? : 的写法

??= 和 += 是一脉的

string? a = null;
var b = a ?? "dada"; // dada
a = a ?? "dada";
a ??= "dada";

must use

22.Record types & Init only setters (9.0)

record 我还没有开始用, 之后才补上, 简单说就是 immuatable 对象啦. 要用 C# 来替代 js 写前端, 那么 C# 本身就得有 js 的灵活. 所以那些以为只要会 C# 配上 blozar 就可以不用学前端那一套, too young too simple.

init only setter, 只有在初始化的时候赋值, 之后就不可写了。注: 用反射依然可以写进去。

public class Person
{
public string Name { get; init; } = "";
public int Age { get; set; }
}
public void OnGet()
{
var person = new Person
{
Name = "dada"
};
person.Name = "a";
}

不错用

23. Fit and finish features (9.0)

WeatherStation station = new() { Location = "Seattle, WA" };

如果类型能被推到出来, 那么就可以不需要在 new 的时候用写多一次类型了.

适用于写入 parameter 的场景哦

public class Person {
public string Name { get; set; } = "";
}
public void Method(Person person)
{ }
public void OnGet()
{
Method(new Person { Name = "dada" }); // 旧
Method(new() { Name = "dada" }); // 新
}

和函数省略 return 做成表达式一样, 不是每个地方省略就一定更好阅读,有时候废话一点也挺好.

省略 != 好, 不推荐

24. Pattern matching enhancements (9.0)

多了 is, not, and, or 等语法. 有点像 sql 那样. 就是少一点符号, 用词来替代.

我觉得挺好的.

public static bool IsLetterOrSeparator(this char c) =>
c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';

关于 pattern 可以看这篇: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/patterns#c-language-specification

switch case when is not and or 这些词语都会经常出现在里头. 目前我的感觉是并没有完全替代原来的 if else || && 这些. 只是语义化了一些, 提高了阅读体验是真的.

有些场景不错用.

C# – 6.0, 7.0, 8.0, 9.0 总结的更多相关文章

  1. Linux下Oracle 10.2.0.1升级到10.2.0.4总结

    最近部署测试环境时,将测试环境ORACLE数据库从10.2.0.1升级到了10.2.0.4,顺便整理记录一下升级过程. 实验环境: 操作系统:Oracle Linux Server release 5 ...

  2. win10安装oracle 11g 报错 要求的结果: 5.0,5.1,5.2,6.0 6.1 之一 实际结果: 6.2

    Windows10下安装Oracle11G.10G,都会提示如下信息 正在检查操作系统要求... 要求的结果: 5.0,5.1,5.2,6.0 之一 实际结果: 6.1 检查完成.此次检查的总体结果为 ...

  3. win10 用cmake 3.5.2 和 vs 2015 update1 编译 GPU版本(cuda 8.0, cudnn v5 for cuda 8.0)

    win10 用cmake 3.5.2 和 vs 2015 update1 编译 GPU版本(cuda 8.0, cudnn v5 for cuda 8.0)  用vs 2015打开 编译Release ...

  4. CMS .NET 程序框架 从2.0/3.5升级到4.0 版本后 需要调整的地方

    问题一: document.forms1.action 不可使用 需要修改程 document.forms[0] .NET 程序框架 从2.0/3.5升级到4.0 版本后,document.forms ...

  5. php4.3.4.4、apache2.0.4.8、mysql 4.0.26、window7 配置过程

    apache的安装不需要过程,直接默认安装,下一步 下一步就Ok了. php4的安装: 1 将php-4.0.4-Win32.zip(最新版本4.0.4)解压缩到硬盘的一个目录中,例如解压到E:php ...

  6. Microsoft.Jet.OLEDB.4.0和Microsoft.ACE.OLEDB.12.0的区别

    Microsoft.Jet.OLEDB.4.0和Microsoft.ACE.OLEDB.12.0的区别 时间 2012-12-19 20:30:12  CSDN博客原文  http://blog.cs ...

  7. (转载) .NET2.0程序集无法在.net 4.0 中运行的解决方案

    首先在MSDN上看到 4.0 的更新日志中有如下这条: .NET Framework 4 不能自动使用自己的公共语言运行时版本来运行由 .NET Framework 早期版本生成的应用程序. 若要使用 ...

  8. CentOS7.0分布式安装HADOOP 2.6.0笔记-转载的

    三台虚拟机,IP地址通过路由器静态DHCP分配 (这样就无需设置host了). 三台机器信息如下 -      1. hadoop-a: 192.168.0.20  #master     2. ha ...

  9. 你好,C++(17)0.1*10不等于1.0——4.1.4 关系操作符4.1.5 逻辑操作符

    4.1.4  关系操作符 在C++中,除了需要用算术操作符对数据进行加减乘除的算术操作之外,我们有时候还需要对数据之间的关系进行操作,也就是对两个数据进行大小比较,得出它们之间的大小关系.在现实世界中 ...

  10. 及格率 不谢 cast(cast (sum(case when res>=60 then 1 else 0 end)*100/(count(1)*1.0) as float) as nvarchar)+'%' '及格率'

    --18.查询各科成绩最高分.最低分和平均分:--以如下形式显示:-- 课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率--及格为>=60,中等为:70-80,优良 ...

随机推荐

  1. [oeasy]python0080_设置RGB颜色_24bit_24位真彩色_颜色设置

    RGB颜色 回忆上次内容 上次 首先了解了 索引颜色 \33[38;5;XXXm 设置 前景为索引色 \33[48;5;XXXm 设置 背景为索引色 RGB每种颜色 可选0-5 总共 6 级 想用 精 ...

  2. 学习笔记--Java合集

    学习笔记--Java合集 JDK8 基础篇 我的第一个Java程序 Java标识符 Java 字面值 Java中的变量 Java中的数据类型 Java 运算符 Java 控制语句 方法 Java方法基 ...

  3. 使用uWSGI+nginx部署Django项目(Ubuntu)

    对于uwsgi+nginx的部署方式,它的访问关系大概是: 1 the web client <-> the web server <-> the socket <-&g ...

  4. Kubernetes kubeadm在Linux下的安装

    实践环境 CentOS-7-x86_64-DVD-1810 开始之前 确保每台机器2G内存或以上 确保每台机器双核CPU或以上 确保所有机器网络互连 确认每个结点(node)的hostname,MAC ...

  5. Fiddler+proxifier解决抓取不到客户端接口的问题

    工作中偶尔会遇到Fiddler抓不到客户端接口问题,那么就要借助第三方工具proxifier来实现了: 下载地址: 原地址:链接: https://pan.baidu.com/s/1JPJ4cILEs ...

  6. 如何让SQL Server像MySQL一样拥有慢查询日志(Slow Query Log慢日志)

    如何让SQL Server像MySQL一样拥有慢查询日志(Slow Query Log慢日志) SQL Server一直以来被人诟病的一个问题是缺少了像MySQL的慢日志功能,程序员和运维无法知道数据 ...

  7. ssh 转发 和 切换图形化

    适用环境 宿主机连接到一台服务器是,服务器系统里面的浏览器点击http网页卡顿,那么这时可以通过ssh将端口转发到宿主机 使用宿主机的浏览器点击,则不会很卡顿. [root@foundation1 ~ ...

  8. 【Java】单号创建服务

    需求:ERP项目存在若干个业务功能,每个业务的单子的单号创建规则需要被统一规划 1.每个业务有自己对应的标识 2.业务单号必须以英文字母为前缀,长度在2 - 4个字符 3.单号的组成 = [ 前缀 ] ...

  9. 【Java】【常用类】Calendar 日历类

    Calendar 日历类,我居然念错发音,来,好好看下音标  ['kælɪndə]  卡琳达 public class DateTest { public static void main(Strin ...

  10. 【C3】03 如何构建

    既然你已经了解了什么是CSS,以及使用CSS的基础知识,是时候更深入的了解该语言本身的结构了. 我们已经见过了本页讨论的很多概念:如果在之后对某些概念感到困惑的话,可以返回至此进行回顾. 前置知识 在 ...