盘点C# 9.0中好用的特性

顶级语句

将类和类里面Main函数省略,只留下核心的逻辑代码就是顶级语句!

1.顶级语句1

await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine("Hi!");
return 0;
static class $Program
{
    static async Task<int> $Main(string[] args)
    {
        await System.Threading.Tasks.Task.Delay(1000);
        System.Console.WriteLine("Hi!");
        return 0;
    }
}

1.顶级语句2

System.Console.WriteLine("Hi!");
return 2;
static class $Program
{
    static int $Main(string[] args)
    {
        System.Console.WriteLine("Hi!");
        return 2;
    }
}

Init

struct Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
}

init通过允许调用方在构造操作过程中改变成员,访问器使不可变对象更具灵活性。 这意味着对象的不可变属性可以参与对象初始值设定项,因此不再需要类型中的所有构造函数样板。 Point类型现在只是:

struct Point
{
    public int X { get; init; }
    public int Y { get; init; }
}

然后,使用者可以使用对象初始值设定项来创建对象。

var p = new Point() { X = 42, Y = 13 };

记录

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

继承

除非类为 object ,且类不能从记录继承,否则记录不能从类继承。 记录可以继承自其他记录。

 public record Student(string name,int age) {
 }
using System;
using System.Collections.Generic;

public class Student : IEquatable<Student>
    {
        #region 属性这部分 可以看到set属性没有
        #记录具有不可变性,记录一旦初始化完成,那么它的属性值将不可修改(可以通过反射修改)
        public string Name { get; init; }
        public int Age { get; init; }
        #endregion

        #region
        protected virtual Type EqualityContract => typeof(Student);
        #endregion
      
        public override bool Equals(object? obj) => Equals(obj as R1);
        public virtual bool Equals(Student? other)
        {
            return !(other is null) &&
                EqualityContract == other.EqualityContract &&
                
                EqualityComparer<string>.Default.Equals(this.Name, other.Name) &&
                EqualityComparer<int>.Default.Equals(this.Age, other.Age);
        }
        public static bool operator ==(R1? left, R1? right)
            => (object)left == right || (left?.Equals(right) ?? false);
        public static bool operator !=(R1? left, R1? right)
            => !(left == right);

         public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("Student");
            builder.Append(" { ");
            if (this.PrintMembers(builder))
            {
                builder.Append(" ");
            }
            builder.Append("}");
            return builder.ToString();
        }
    }

支持解构

public record Student(string Name, int Age) {
        public string Name { get; set; }
        public int Age { get; set; }
}
Student record = new Student("张三",19) ;
var (name, age) = record;

==》这个可以用在switch匹配上 还记得我们
string value = record switch{
                ("张三", 19) => "01",
                ("李四", 25) => "02",
                _ => "default"
 };

## 之所以可以用这个这么用 是因为编译后多了这样的解构函数
 public void Deconstruct(out string Name, out int Age) => (Name, Age) = (this.Name, this.Age);

with 表达式

with表达式是使用以下语法的新表达式。

Student record2  = record with { Name = "王五" };

//在编译后等价于
var temp = record.<Clone>$();
temp.Name = "王五";
record2 = temp;

//不赋值 完全克隆
Student record3  = record with { };

好处:

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

Lambda 弃元参数

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

  • lambda: (_, _) => 0 , (int _, int _) => 0
  • 匿名方法: delegate(int _, int _) { return 0; }
public delegate void FuncA(string a, string c);

        static void Main(string[] args)
        {

            FuncA func = (_, _) => { };

        }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • 增加引用类型可为null: 模式匹配 1、swith 多条件匹配 Using 声明 接口特性增加 --- 可以声明...
    程序员ken阅读 198评论 0 0
  • 上学时学习C#和.NET,当时网上的资源不像现在这样丰富,所以去电脑城买了张盗版的VS2005的光盘,安装时才发现...
    编程小世界阅读 304评论 0 0
  • C#2.0泛型:泛型可以帮助我们实现代码的重用,同时泛型的另一个好处——高性能,并且泛型类型也保证了类型安全部分类...
    OMG_1bcc阅读 1,037评论 0 0
  • 本文按照 cppreference[https://en.cppreference.com/w/] 列出的特性列表...
    401阅读 20,996评论 2 18
  • 记录自己在学习c#遇到的知识点(容易忽略容易忘记得,或一些小技巧)[持续更新] 前言: 在大部分应用情况下,"效率...
    wwmin_阅读 1,143评论 0 51