What is the new in C#11?
目录
Raw String Literals
List Pattern
Slice Pattern
Var Pattern
File Local Types
Required Members
Auto Default Structs
Ref Fields
Raw String Literals
"""里面的内容是space敏感的。 意思是如果”age”前面有几个空格,就会打印几个空格。
/*
{
"name":"Evan",
"age": 37
}
*/
//older than C#11
string json = "{\r\n \"name\":\"Evan\",\r\n \"age\": 37\r\n}";
//C#11 new feature
string json2 = """
{
"name":"Evan",
"age": 37
}
""";
//“age”前面的space数量与最下面的"""空格数量不一致,会编译报错
string json_Error = """
{
"name":"Evan",
"age": 37
}
""";
List Pattern
/*
* RUle 1: should contains only 2 elements
* Rule 2: The element 0 should be 10
* Rule 3: The element 1 should be less than 25
* RUle 4: The element 2 should be equals 50 and 60
*
*/
int[] values = { 10, 20, 60 };
//older
bool verify1 = values.Length == 3 && values[0] == 10 && values[1] < 25 && (values[2] == 50 || values[2] == 60);
//New in C# 11
bool verify2 = values is [10, < 25, 50 or 60];
Slice Pattern
Console.WriteLine(new List<int> { 10, 20, 60 } is [10, < 25, 50 or 60]);//True
Console.WriteLine(new List<int> { 10, 20, 30, 60 } is [10, < 25, _, 50 or 60]);//True. _ 代表index=2的位置
Console.WriteLine(new List<int> { 10, 20, 30, 60, 70, 80 } is [10, < 25,.., 50 or 80]);//True. ..代表 30, 60, 70
Console.WriteLine(new List<int> { 10, 20, 30, 60, 24, 80 } is [.., < 25, 50 or 80]);//True. ..代表 10, 20, 30, 60,
Console.WriteLine(new List<int> { 10, 20, 30, 60, 24, 80 } is [10, < 25, ..]);//True. ..代表 30, 60, 24, 80
//Console.WriteLine(new List<int> { 10, 20, 30, 60, 24, 80 } is [10,.., < 25, ..]);//Compiler error
Var Pattern
Console.WriteLine(new List<int> { 10, 20, 60 } is [10, var a, var b] && (a == 20 && b == 60));
Console.WriteLine(new List<int> { 10, 20, 60 } is [10, var x and >= 20, var y] && y == 60);
var person = new Person("Evan", "Wang", 37);
Console.WriteLine(person is ("Evan", "Wang", > 35));//true
Console.WriteLine(person is ("Zhen", "Wang", 37));//false
Console.WriteLine(person is ("Zhen", "Wang", 37) and var (firstName, lastName, age) && age >= 35);//true
File Local Types
个人感觉没啥用,internal class可以代替这个class,唯一不用的是internal class是libarary内部级别的,file class是文件级别的(即只有相同文件里面可以引用)。
//Program.cs
TestFileClass test = new TestFileClass();
test.Print();//Print: ABC AdditionalTestFileClass
//var fileClass = new AdditionalTestFileClass();//Compiler error
//TestFileClass.cs
internal class TestFileClass
{
public void Print()
{
var value = new AdditionalTestFileClass().GetAdditinalPrint();
Console.WriteLine($"ABC {value}");
}
}
file class AdditionalTestFileClass
{
public string GetAdditinalPrint()
{
return "AdditionalTestFileClass";
}
}
Required Members
public class RequiredDemo
{
public required string Name { get; set; }
}
//var c1=new RequiredDemo();//Compile time Error: you must initialize the required property
var c2=new RequiredDemo() {Name="Evan"};//set value for required property
Auto Default Structs
public struct Point
{
public int X;
public int Y;
// 构造函数(可选)
public Point(int x, int y)
{
X = x;
Y = y;
}
// 无参数的构造函数(可选,但在结构体中不常见)
// public Point() { } // 这将允许Point p = new Point(); 但通常不需要
}
// 使用
Point p1 = new Point(1, 2); // 使用构造函数显式初始化
Point p2 = default(Point); // 使用default关键字获取默认实例
Point p3 = new Point(); // 如果没有定义无参数构造函数,这将是一个编译错误
// 但如果你确实定义了无参数构造函数,则上面的代码是有效的,但通常不推荐这样做,因为默认(Point)已经足够了
// C# 7.1+ 可以使用目标类型新表达式
Point p4 = new(); // 仅当结构体定义了无参数构造函数时有效,或者使用了编译器对default的改进
Ref Fields
Limitation:
- A ref struct can't be the element type of an array.
- A ref struct can't be a type of a field of a class or non-ref struct
- A ref struct can't impement interfaces
- A ref struct can't be boxed to System.ValueType of System.Object
- A ref struct can't be a type argument for generic (泛型)types or generic methods.
- A ref struct variable can't be captured in a lambda expression or a local function.
- Before C#13, ref struct variables can't be used in an async method.
- Beignning with C#13, ref struct variables canbe used until "await" keyword apprears..
int value = 37;
StructA a = new StructA();
a.filed = value;
RefStructA refA = new RefStructA(ref value);
Console.WriteLine($"a=={a.filed}");//a==37;
Console.WriteLine(value);//37;
Console.WriteLine($"ref a=={refA.filed}");//ref a==37;
value = 18;
Console.WriteLine($"a=={a.filed}");//a==37;
Console.WriteLine(value);//18;
Console.WriteLine($"ref a=={refA.filed}");//ref a==18;
public struct StructA
{
public int filed;
}
public ref struct RefStructA
{
public ref int filed;
public RefStructA(ref int a)
{
filed = ref a;
}
}