翼度科技»论坛 编程开发 .net 查看内容

盘点C# 9.0中好用的特性

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
顶级语句

将类和类里面Main函数省略,只留下核心的逻辑代码就是顶级语句!
1.顶级语句1
  1. await System.Threading.Tasks.Task.Delay(1000);
  2. System.Console.WriteLine("Hi!");
  3. return 0;
复制代码
  1. static class $Program
  2. {
  3.     static async Task<int> $Main(string[] args)
  4.     {
  5.         await System.Threading.Tasks.Task.Delay(1000);
  6.         System.Console.WriteLine("Hi!");
  7.         return 0;
  8.     }
  9. }
复制代码
1.顶级语句2
  1. System.Console.WriteLine("Hi!");
  2. return 2;
复制代码
  1. static class $Program
  2. {
  3.     static int $Main(string[] args)
  4.     {
  5.         System.Console.WriteLine("Hi!");
  6.         return 2;
  7.     }
  8. }
复制代码
Init
  1. struct Point
  2. {
  3.     public int X { get; }
  4.     public int Y { get; }
  5.     public Point(int x, int y)
  6.     {
  7.         this.X = x;
  8.         this.Y = y;
  9.     }
  10. }
复制代码
init通过允许调用方在构造操作过程中改变成员,访问器使不可变对象更具灵活性。 这意味着对象的不可变属性可以参与对象初始值设定项,因此不再需要类型中的所有构造函数样板。 Point类型现在只是:
  1. struct Point
  2. {
  3.     public int X { get; init; }
  4.     public int Y { get; init; }
  5. }
复制代码
然后,使用者可以使用对象初始值设定项来创建对象。
  1. var p = new Point() { X = 42, Y = 13 };
复制代码
记录

记录类型是引用类型,类似于类声明。 如果不包含,记录将提供一个错误 record_base argument_list record_declaration parameter_list 。 部分记录最多只能有一个分部类型声明提供 parameter_list 。
记录参数不能 ref 使用 out 或 this 修饰符 (但 in params 允许) 。
继承

除非类为 object ,且类不能从记录继承,否则记录不能从类继承。 记录可以继承自其他记录。
  1. public record Student(string name,int age) {
  2. }
复制代码
  1. using System;
  2. using System.Collections.Generic;
  3. public class Student : IEquatable<Student>
  4.     {
  5.         #region 属性这部分 可以看到set属性没有
  6.         #记录具有不可变性,记录一旦初始化完成,那么它的属性值将不可修改(可以通过反射修改)
  7.         public string Name { get; init; }
  8.         public int Age { get; init; }
  9.         #endregion
  10.         #region
  11.         protected virtual Type EqualityContract => typeof(Student);
  12.         #endregion
  13.       
  14.         public override bool Equals(object? obj) => Equals(obj as R1);
  15.         public virtual bool Equals(Student? other)
  16.         {
  17.             return !(other is null) &&
  18.                 EqualityContract == other.EqualityContract &&
  19.                
  20.                 EqualityComparer<string>.Default.Equals(this.Name, other.Name) &&
  21.                 EqualityComparer<int>.Default.Equals(this.Age, other.Age);
  22.         }
  23.         public static bool operator ==(R1? left, R1? right)
  24.             => (object)left == right || (left?.Equals(right) ?? false);
  25.         public static bool operator !=(R1? left, R1? right)
  26.             => !(left == right);
  27.          public override string ToString()
  28.         {
  29.             StringBuilder builder = new StringBuilder();
  30.             builder.Append("Student");
  31.             builder.Append(" { ");
  32.             if (this.PrintMembers(builder))
  33.             {
  34.                 builder.Append(" ");
  35.             }
  36.             builder.Append("}");
  37.             return builder.ToString();
  38.         }
  39.     }
复制代码
支持解构
  1. public record Student(string Name, int Age) {
  2.         public string Name { get; set; }
  3.         public int Age { get; set; }
  4. }
复制代码
  1. Student record = new Student("张三",19) ;
  2. var (name, age) = record;
  3. ==》这个可以用在switch匹配上 还记得我们
  4. string value = record switch{
  5.                 ("张三", 19) => "01",
  6.                 ("李四", 25) => "02",
  7.                 _ => "default"
  8. };
  9. ## 之所以可以用这个这么用 是因为编译后多了这样的解构函数
  10. public void Deconstruct(out string Name, out int Age) => (Name, Age) = (this.Name, this.Age);
复制代码
with 表达式

with表达式是使用以下语法的新表达式。
  1. Student record2  = record with { Name = "王五" };
  2. //在编译后等价于
  3. var temp = record.<Clone>$();
  4. temp.Name = "王五";
  5. record2 = temp;
  6. //不赋值 完全克隆
  7. Student record3  = record with { };
复制代码
好处:

1.比较两个属性是否相等跟属性设置的顺序无关
2.方便快速克隆,不影响原数据
3.补充了结构体不支持继承以及性能不高的短处


Lambda 弃元参数

允许丢弃 (用作 _ lambda 和匿名方法的参数) 。 例如:

  • lambda: (_, _) => 0 , (int _, int _) => 0
  • 匿名方法: delegate(int _, int _)
  1. public delegate void FuncA(string a, string c);
  2.         static void Main(string[] args)
  3.         {
  4.             FuncA func = (_, _) => { };
  5.         }
复制代码
来源:https://www.cnblogs.com/kenower/archive/2023/04/22/17343885.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具