自从我因各种原因与C# 7.0打交道以来,时间已经过去了,它变成了C# 11.0。
所以,我想编写我个人认为有用的从C# 8.0 到C# 11.0 的函数。
就个人而言,我专注于我想在 Unity 等中使用的部分,因此可能会有此处未列出的更新。请阅读官方文档。
C# 8.0
可空引用类型
直到现在,像string 这样的引用类型必须可以为空。
换句话说,对于引用类型,总是有可能出现NullReferenceException,而我的前辈和我已经通过“Null Object”设计模式阻止了这种情况。
(例如,“string.Empty”适用于string)
但是,C# 8.0 现在有一个选择加入选项,默认情况下使 T 类型不可为空。
(如果不进行空检查会出现警告)
这个功能是pragma
#nullable enable
通过写入启用
如果您想在该文件中临时恢复为可空性(默认),请写入“T?”以使其可空。
开关表达式
switch 现在可以写成表达式。
public int Compare(int? x, int? y) => (x, y) switch {
(int i, int j) => i.CompareTo(j),
({ }, null) => 1,
(null, { }) => -1,
(null, null) => 0
};
范围访问
通过为使用数组和列表等下标访问的类指定“i..j”,现在可以“取出第 i 个到第 j 个元素”。
public void Method(List<int> list)
{
var trim = list[1..^1];
}
此外,通过像[i..^j] 一样将^ 添加到后下标,您可以“删除j”。
所以你可以写[1..^1]把两端一一去掉。
使用变量声明
using 现在可以在“变量”而不是“范围”上完成。
转义该变量的范围时,它似乎是Dispose()。
public void Method()
{
using var a = new DisposableObject();
}
空合并赋值
关于??=。
可用于缓存。
private Dictionary<int, string> _dict;
public void Method(int index, string message)
{
_dict[index] ??= message;
}
@$ 的顺序
@ 和 $ 是字符串补全表达式,它们一起使用时只允许使用“$@”,但现在也允许使用“@$”。
Obsolete 访问者规范
Obsolete 现在只能为一个访问者指定。
public int Position
{
[Obsolete] set;
get;
}
C# 9.0
记录类型
面向对象1在 中,“类如何表现”很重要,“它是如何(实现)”并不重要,但有时需要数据本身。2,我们现在有一种可用于数据的类型,称为“记录类型”。
using System;
record Player(string id, string Name);
让我高兴的是,在处理数据时,有时会进行比较。
在这种情况下,需要覆盖数据类中的Equals(),并逐个比较字段,或者覆盖GetHashCode()。
但是,在这种记录类型中,“Equals”、“GetHashCode”和“==”似乎是自动生成的,因此无需编写那种礼貌的代码。
初始化访问器
通过写“init”而不是set,现在可以创建一个可以重写到初始值设定项并且之后不能重写的属性。
class Clazz
{
public int Value { init; get; }
}
顶级声明
你可以在顶层写句子。
using System;
Console.WriteLine("Hi there, This is Top Level.");
int Add(int x, int y) => x + y;
似乎整个项目只能写入一个文件。
为模式匹配添加模式
您可以使用not, and, or。
public bool Method(int index) => index is 0 or 9;
public bool IsNotString(object s) => s is not string;
new() 类型推断
类型推断现在适用于具有指定类型的字段和变量。
public void Method()
{
SomeClass s = new ();
}
当你想要一个类型名称很长的类型(例如Dictionary<int, List<(double x, double y)>>)作为字段时,你可以使用 new () 作为初始化器,使其更短。
协变返回值
virtual指定方法的返回值现在可以在子类中更改。SubClazz 可以安全地转换(向上转换)为BaseClazz,所以这是一个合理的规范。
class BaseClazz
{
virtual BaseClazz Clone() => new BaseClazz();
}
class SubClazz : BaseClazz
{
override SubClazz Clone() => new SubClazz();
}
本机 int (*需要不安全)
通过使用nint 和nuint 关键字,您现在可以指定操作环境中最快的整数。
unsafe
{
nint x = 0b_1;
}
在 lambda 表达式中丢弃
现在可以丢弃 Lambda 表达式。为了向后兼容,_ 仅在出现多次时才有效。
(_, _) => { };
C# 10.0
C# 10.0 及更高版本尚不能在 Unity 中使用。
值类型记录
现在可以将记录类型指定为值类型。
using System;
record struct Position(int X, int Y);
文件范围命名空间
现在可以将命名空间指定为语句,而不是像以前那样指定由范围覆盖的命名空间。
namespace Assets;
class Clazz
{
}
全区使用
using 现在可以影响整个项目。
global using System;
顺便说一句,如果您在 Unity 中执行此操作,如果未指定完整类型名称,System.Random 和 UnityEngine.Random 将不明确。
扩展解构声明和解构赋值
这种写作风格现在是可以接受的。
public void Method()
{
int x;
(x, var y) = (1, 2);
}
C# 11.0
必需成员
为属性和字段添加了required 修饰符。
生成该类时,必须在初始化程序中指定一个值。
public class Clazz
{
public required string ID { init; get; }
}
原始字符串
现在可以使用""" 使用原始字符串。
按原样处理,{} 按原样处理 {}。
下面代码中的ID_Format 变成了字符串“ID: {ID}”。
public string ID_Format = """ID: {ID}""";
如果你想完成,你可以使用$$"""""" 和{{}}3.
public string ID_Format = $$"""{"ID": "{{FieldID}}"}""";
如果要在原始字符串中使用""",请添加 1 ",""" 将被视为文字字符。
也就是说,如果你写"""" """ """",它就变成了“"""”,
如果你写""""" """" """"",它就变成了“""""”。
针对列表的模式匹配
您现在可以对列表和数组进行模式匹配。
public bool IsEmptyOrSingle(List<int> list) => list switch
{
[] or [_] => true,
_ => false,
};
请注意,[] 中的内容是模式,而不是索引或大小。
换句话说,如果您在列表的模式匹配中编写[1, ..],它将是“第一个元素为 1 的列表”而不是“具有 1 个元素的列表”。
总是无符号右移
>>> 已添加。
解除对移位运算符右操作数的限制
到目前为止,移位运算符的右侧必须是 int,但现在您可以指定除 int 以外的类型。
public static Clazz operator <<(Clazz a, Clazz i) => default;
Generic Math 这似乎是实现的补充。
严禁滥用4.
文件本地类型
我们现在有了只能在同一个文件中使用的修饰符。
file static class Extension
{
}
file enum SomeEnum
{
None,
}
但是,文件只能在顶级位置指定。
字符串插值期间的换行符
它是在@$ 中完成的,所以它更像是一个错误修复。
public static string ID = $"id:{
someExternalID
}";
无法指定上下文关键字的类型名称
如果将C# 11.0添加的context关键字指定为如下所示的类型名称,则会出现错误。
到目前为止,上下文关键字只产生警告,而不是错误。
class file { }
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308632065.html