C#新语法2

可空的引用类型(C#8)

1、复习:C#数据类型分为值类型和引用类型两种,值类型的变量不可以为空,而引用类型变量可以为空

2、问题:如果不注意检查引用类型变量是否可空,就有可能造成程序中出现NullReferceException异常

3、csproj中<Nullable>enable</Nullable>启用可空引用类型检查,默认是启用的,建议启用

4、在引用类型后加“?”修饰符来声明这个类型时可空的。对于没有添加“?”修饰符的引用类型的变量,如果编译器发现存在为这个变量赋值null的可能性的时候,编译器会给出警告信息

有警告的声明

消除警告(加上?)

有警告的代码

消除警告的代码

使用!来抑制警告

如果程序员确认被访问的变量、成员确实不会出现为空的情况,也可以在访问可空的变量、成员的时候加上!来抑制编译器的警告。不要滥用

Student s1 = GetData();
Console.WriteLine(s1.Name.ToLower());
Console.WriteLine(s1.PhoneNumber!.ToLower());

记录(record)类型(C#9)

1、C#中的==运算符默认是判断两个变量指向的是否是同一个对象,即使两个对象内容完全一样,也不相等。可以通过重写Equals方法、重写==运算符等来解决这个问题,不过需要开发人员编写非常多的额外代码。

2、在C#9.0中增加记录(record)类型的语法、编译器会为我们自动生成Equals、GetHashcode等方法。

public record Person(string FirstName, string LastName);

输入以下代码,发现==和ToString已经被重写

Person p1 = new Person("Yang", "Zack");
Person p2 = new Person("Yang","Zack");
Person p3 = new Person("Gates", "Bill");
Console.WriteLine(p1.ToString);//Person{id = ?,Name = ?,Age = ?}
Console.WriteLine(p1==p2);//False
Console.WriteLine(p1==p3);//True

record的的原理及深入

原理探究

  1. 编译器会根据Person类型中的属性定义,自动为Person类型生成包含全部属性的构造方法。注意,默认情况下,编译器会生成已给包含所有属性的构造方法,因此,我们编写new Person()、new Person("Yang")这两种写法都是不可以的。也会生成ToString方法和Equals等方法。
  2. 通过反编译看背后原理。避免反编译的优化,需要把反编译器生成的代码改成C#8.0的语法。结论:record就是普通的一个类。
  3. record数据类型为我们提供了为所有属性赋值的构造方法,所以有属性都是只读的,而且对象可以进行值相等性比较,并且提供了可读性强的ToString()返回值。在需要编写一些不可变类并且需要进行对象,record可以帮助我们把代码的编写难度大大降低

record深入

  1. 可以实现部分属性是只读的、而部分属性是可以读写。
  2. 默认生成的构造方法的行为不能修改,我们可以为类型提供多个构造方法,然后其他构造方法通过this调用默认的构造方法
  3. 也推荐使用只读属性的类型。这样的所有属性都为只读的类型叫做“不可变类型”,可以让程序逻辑简单,减少并发访问、状态管理等的麻烦。

对象的副本

1、record也是普通类,变量的赋值是引用的传递。这是和结构体不同之处

2、生成一个对象的副本,这个对象的其他属性值与原对象相同,只有一个或者少数几个属性改变。麻烦的做法:

User u2 = new User(u1.UserName, "test@example", u1.Age);

3、用with关键字简化:

User u2 = u1 with { Email= “test@example” }; 

创建的也是拷贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值