.NET Core 3.x
和.NET Standard 2.1
支持C# 8.0
。
一、Readonly 成员可将 readonly
修饰符应用于结构的成员 , 来限制成员为不可修改状态 。这比在C# 7.2
中将 readonly
修饰符仅可应用于 struct
声明更精细 。
public struct Point{public double X { get; set; }public double Y { get; set; }public double Distance => Math.Sqrt(X * X + Y * Y);public override string ToString() =>$"({X}, {Y}) is {Distance} from the origin";}
与大多数结构一样,ToString()
方法不会修改状态 。可以通过将 readonly
修饰符添加到 ToString()
的声明来对此进行限制:
public readonly override string ToString() =>// 编译器警告,因为 ToString 访问未标记为 readonly 的 Distance 属性$"({X}, {Y}) is {Distance} from the origin";// Distance 属性不会更改状态 , 因此可以通过将 readonly 修饰符添加到声明来修复此警告public readonly double Distance => Math.Sqrt(X * X + Y * Y);
注意:readonly
修饰符对于只读属性是必需的 。
编译器会假设 get
访问器可以修改状态;必须显式声明 readonly
。
自动实现的属性是一个例外;编译器会将所有自动实现的 Getter
视为 readonly
, 因此,此处无需向 X
和 Y
属性添加 readonly
修饰符 。
通过此功能 , 可以指定设计意图,使编译器可以强制执行该意图,并基于该意图进行优化 。
二、默认接口方法从 .NET Core 3.0
上的 C# 8.0
开始,可以在声明接口成员时定义实现 。最常见的方案是,可以将成员添加到已经由无数客户端发布并使用的接口 。示例:
// 先声明两个接口// 客户接口public interface ICustomer{IEnumerable<IOrder> PreviousOrders { get; }DateTime DateJoined { get; }DateTime? LastOrder { get; }string Name { get; }IDictionary<DateTime, string> Reminders { get; }// 在客户接口中加入新的方法实现public decimal ComputeLoyaltyDiscount(){DateTime TwoYearsAgo = DateTime.Now.AddYears(-2);if ((DateJoined < TwoYearsAgo) && (PreviousOrders.Count() > 10)){return 0.10m;}return 0;}}// 订单接口public interface IOrder{DateTime Purchased { get; }decimal Cost { get; }}// 测试代码// SampleCustomer:接口 ICustomer 的实现,可不实现方法 ComputeLoyaltyDiscount// SampleOrder:接口 IOrder 的实现SampleCustomer c = new SampleCustomer("customer one", new DateTime(2010, 5, 31)){Reminders ={{ new DateTime(2010, 08, 12), "childs's birthday" },{ new DateTime(1012, 11, 15), "anniversary" }}};SampleOrder o = new SampleOrder(new DateTime(2012, 6, 1), 5m);c.AddOrder(o);//添加订单o = new SampleOrder(new DateTime(2103, 7, 4), 25m);c.AddOrder(o);// 验证新增的接口方法ICustomer theCustomer = c; // 从 SampleCustomer 到 ICustomer 的强制转换Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");// 若要调用在接口中声明和实现的任何方法 , 该变量的类型必须是接口类型,即:theCustomer
三、模式匹配的增强功能C# 8.0
扩展了C# 7.0
中的词汇表(is
、switch
),这样就可以在代码中的更多位置使用更多模式表达式 。
3.1 switch 表达式区别与 switch 语句:
??变量位于 switch 关键字之前;
??将 case 和 : 元素替换为 =>,更简洁、直观;
??将 default 事例替换为 _ 弃元;
??实际语句是表达式,比语句更加简洁 。
public static RGBColor FromRainbow(Rainbow colorBand) =>colorBand switch{Rainbow.Red=> new RGBColor(0xFF, 0x00, 0x00),Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),Rainbow.Green=> new RGBColor(0x00, 0xFF, 0x00),Rainbow.Blue=> new RGBColor(0x00, 0x00, 0xFF),Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),_=> throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),};
3.2 属性模式借助属性模式,可以匹配所检查的对象的属性 。
如下电子商务网站的示例 , 该网站必须根据买家地址(Address 对象的 State 属性)计算销售税 。
// Address:地址对象;salePrice:售价public static decimal ComputeSalesTax(Address location, decimal salePrice) =>location switch{{ State: "WA" } => salePrice * 0.06M,{ State: "MN" } => salePrice * 0.075M,{ State: "MI" } => salePrice * 0.05M,// other cases removed for brevity..._ => 0M};
推荐阅读
- 在FreeSQL中实现「触发器」和软删除功能
- 小米12x和小米12pro区别-小米12x和小米12屏幕一样吗
- 华为手环6和华为fit哪个好_华为手环6和华为fit对比
- 小米civi和荣耀50pro区别对比_哪款更值得买
- 中国标准的青年和中年的年龄段分别是多少 中国青年年龄
- s20 fe 5g和s20区别_三星s20 fe 5g和三星s20区别
- 华为智慧屏s65和v65区别是什么_华为智慧屏s65和v65电视对比
- 微信怎样通过添加好友申请(微信发送添加好友申请)
- 用微信账号怎么添加好友(微信怎么查自己主动添加好友记录)
- 如何添加微信好友(微信加满5000好友技巧)