C#8.0到10的特性总结

个人推荐去微软官方文档查看,以下是个人总结,不全
微软官方文档:https://learn.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-10

8.0特性 8.0特性一览

1、可空类型:

运行int?这种写法,意为int肯能为null

2、async/await允许直接获取结果

var a = await ……;
配合IAsyncEnumerable,可异步循环返回结果

async IAsyncEnumerable<int> GetBigResultsAsync() {
    await foreach (var result in GetResultsAsync()) {
        if (result > 20) yield return result; 
    }
}

3、Ranges and indices 范围和索引

Index i1 = 3;
Index i2 = ^4;
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"
var slice = a[i1..i2]; // { 3, 4, 5 }

4、接口成员的默认实现

给已有接口添加方法时,可默认实现方法,防止编译失败

interface AA {
    void Test() => Console.WriteLine("11");
}

5、递归的模式匹配

public class Program {

    public static void Main(string[] args) {
        Student[] student = new Student[] {
            new Student{ Graduated = true, Name="0" },
            new Student{ Graduated = false, Name="1" },
            new Student{  Name="2" },
            new Student{ Graduated = true },
            new Student{ Graduated = true, Name=null },
            new Student{ Graduated = true, Name="5" },

        };
        Console.WriteLine(string.Join(",", GetEnrollees(student)));
    }

    static IEnumerable<string> GetEnrollees(Student[] People) {
        foreach (var p in People) {

            if (p is Student { Graduated: true, Name: string name })
                yield return name;
        }
    }

}
class Student {
    public bool Graduated;
    public string Name;
}

关键代码解释:p is Student { Graduated: true, Name: string name }
Graduated: true:判断p里面的Graduated参数必须为true
Name: string name,对p里面的Name进行取值(如果可为空)
等效于

if (p is Student s && s.Graduated == true && s.Name != null) {
    string neme = p.Name;
}

为何会有个s.Name != null,因为string是可空类型,不是可空将不会进行空值判断,例如int不是可空类型,但是int?是

6、switch表达式

匹配模式的增强

int num = 2;
string text = num switch {
    1 => "1",
    2 => "2",
    _ => "3"//default
};

7、已知目标类型的新表达式

public class Program {
    public static void Main(string[] args) {
        Student[] arr = { new(0, "0"), new(true) };
    }
}
class Student {
    public Student(int a, string b) {

    }
    public Student(bool b) {

    }
}

9.0特性9.0特性一览

1、init关键字

init代替set,意为:只允许初始化时赋值,后续不可赋值

public class Program {
    public static void Main(string[] args) {
        Student s = new Student { name = "a" };
        s.name = "b";//异常,不可赋值
    }
}
class Student {
    public string name { get; init; }
}

2、record关键字

个人简单理解:赋予结构体相关特性,进行视为值类型
C#中的记录(record)

3、with关键字

非破坏性拷贝,配合record或struct,拷贝数据

public class Program {
    public static void Main(string[] args) {
        Student s = new Student { name = "a", age = 18 };
        Student s2 = s with { age = 10 };
        AA a = new AA { name = "" };
        AA a2 = a with { name = "a" };
    }
}
record class Student {
    public string name;
    public int age;
}
struct AA {
    public string name;
}

4、顶层语句

整个cs文件就这么点内容也能运行

string name = "1";
Console.WriteLine(name);

5、匹配模式增强

模式匹配是在 C# 7.0 引入的,是对 switch 语句的增强,可以支持实现复杂的条件匹配

public class Program {
    public static void Main(string[] args) {
        A a = new B();
        int num = a switch {
            B { numb: 10 } => 0,//如果a是B类型,并且参数numb是10,则返回0
            B => -1,//default语句,如果是B类型,但都匹配不上,则返回-1

            C c => c.numc switch {//如果是C类型,对C类型的numc进行匹配模式
                > 10 => 1,//如果大于10,返回1
                > 0 and < 5 => 2,//如果大于0小于5,返回2,还有or、not 关键字,优先级is > not > and > or
                _ => -2//都不匹配返回-2
            },
            
            not null => 3,//不是空返回3
            _ => 4
        };
    }
}
class A {
    public int numa;
}
class B : A {
    public int numb;
}
class C : A {
    public int numc;
}

6、返回值类型协变

重写时可对返回值类型具体化

class A {
}
class B : A {
}
abstract class C {
    public abstract A Test();
}
class D : C {
    public override B Test() {//用B,进行更具体的返回
        throw new NotImplementedException();
    }
}

7、本地大小的整型nint/nuint

这两种类型的大小是32还是64的取决于所用平台。在被编译之后,这两个关键字会被转换为System.IntPtr 和System.UIntPtr。

8、静态匿名方法

public class Program {
    public static void Main(string[] args) {
        int num = 10;
        Action<int> nc = static (int a) => Console.WriteLine(a + num);//异常,加static后无法捕获num
        Action<int> nc2 = static delegate (int a) { Console.WriteLine(a + num); };//异常,加static后无法捕获num
    }
}

9、模块初始化器

类似于静态构造方法的另一种实现
C# 9.0新特性详解系列之三:模块初始化器

10、本地函数支持Attribute

静态方法和extern关键字修饰的也支持特性了[]

11、partial可用于方法上

partial class MyClass {
    // 正确,因为没有定义或者实现要求
    partial void Method1();// 正确,因为M2已经有了一个定义和实现了
    private partial void Method2();// 错误,含有显式访问修饰符的分部方法声明必须有一个实现
    private partial void Method3();
}partial class MyClass {
    private partial void Method2() { }
}

12、Lambda弃元参数

就是_字符

    public static void Main(string[] args) {
        Action<int> a = (int _) => Console.WriteLine("OK");
    }

13、目标类型推导

public class Program {
    public static void Main(string[] args) {
        string[] s2 = new[] { "a", "b" };
        Test t = new(2);
        //同时支持??, ?:表达式
    }
}
class Test {
    public Test(int a) {

    }
}

10.0特性10.0特性一览

1、record支持给struct修饰

2、struct支持无参构造

3、with支持支持匿名类

public class Program {
    public static void Main(string[] args) {
        var a = new { name = "张三", age = 10 };
        var b = a with { age = 18 };//name已经是张三
    }
}

4、全局using

using前面加global,作用到全局,可单独创个文件写

5、文件范围的namespace

写法:namespace xxxxxx;

6、const string支持$""写法

const string t = "99";
const string s = $"12{t}4";

7、lambda表达式升级

    public static void Main(string[] args) {
        var a = [DebuggerStepThrough] () => 1;//lambda支持特性
        var b = ref int (ref int num, out int num2) => {
            num2 = 10;
            num += 10;
            return ref num;
        };//支持ref、in、out修饰符

        //隐式转换为delegata
        Func<int> f = a;
        void Test() { Console.WriteLine("OK"); };
        var f2 = Test;
        f2();

        //自动创建自然委托类型
        var t1 = () => 1;//Func<int>
        var t2 = string (int a1, string a2) => $"{a1}{a2}";//Func<int, string, string>
    }

8、CallerArgumentExpression特性

可以方便调试,Release版本也行

public class Program {
    public static void Main(string[] args) {
        Test(9 * 8 - 10);//9 * 8 - 10=62
        int a = 10;
        Test(a + 5);//a + 5=15
    }
    public static void Test(int num, [CallerArgumentExpression("num")]string text = null) {
        Console.WriteLine($"{text}={num}");
    }
}

9、System.ValueTuple支持混合定义和使用

int a = 0;
(var b, a, var c) = (1, 2, 3);//a等于2的同时创建了2个新变量

10、Attribute支持泛型

11、运行在方法上指定[AsyncMethodBuilder]

12、#line指示器支持行列和范围

13、嵌套模式匹配升级

var a = xxxx;
if (a is { X.Y.Z:4 }) {//a的X中的Y中的Z是4就匹配
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值