尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

C# 各版本语法新功能汇总、global using record init

C# 各版本语法新功能汇总、global using record init C# 12》》可以将主构造函数定义为类声明的一部分publicclassContainer(intcapacity){privateint_capacitycapacity;}//之前publicclassContainer{privateint_capacity;publicContainer(intcapacity){_capacity}//可以简化publicContainer(intcapacity)_capacitycapacity;}C# 10》》》全局using指令C# 10.0中增加了“全局using指令”语法我们可以将global修饰符添加到任何using关键字前这样通过using语句引入的命名空间就可以应用到这个项目的所以源代码中因此同一个项目中的C#代码就不需要再去重复引入这个命名空间了。在实践中通常专门创建一个来编写全局using代码的文件然后把项目中经常用到的命名空间声明到这个C#文件。global using ;C# 9record》》init》》publicclassPerson{publicstringName{get;privateset;}publicintAge{get;privateset;}publicPerson(stringname,intage){Namename;// ✅ 构造函数中可以设置Ageage;// ✅ 构造函数中可以设置}publicvoidChangeName(stringnewName){NamenewName;// ✅ 类内部方法中可以修改}publicvoidBirthday(){Age;// ✅ 类内部方法中可以修改}}// 使用varpersonnewPerson(张三,25);Console.WriteLine(person.Name);// ✅ 可以读取// person.Name 李四; // ❌ 编译错误外部不能修改person.ChangeName(李四);// ✅ 通过内部方法修改publicclassProduct{publicstringName{get;init;}publicdecimalPrice{get;init;}publicstringCategory{get;init;}// 可以有构造函数但不是必须的publicProduct(){}publicProduct(stringname,decimalprice){Namename;// ✅ 构造函数中可以设置Priceprice;// ✅ 构造函数中可以设置}}// 使用varproduct1newProduct(手机,2999.99m);// product1.Price 1999.99m; // ❌ 编译错误初始化后不能修改// 对象初始化器语法varproduct2newProduct{Name笔记本,// ✅ 对象初始化时可以设置Price5999.99m,// ✅ 对象初始化时可以设置Category电子产品};// product2.Name 台式机; // ❌ 编译错误初始化后不能修改// 定义一个record类型publicrecordPerson(stringName,intAge);// 使用record类型创建记录实例PersonpersonnewPerson(张三,30);// 使用Console.WriteLine记录记录实例Console.WriteLine($姓名{person.Name}, 年龄{person.Age});Record VS Classrecord资料C# 8.0》》》using// 8.0 之前using(Fontf2newFont(黑体,12FontStyle.Blod)){f2.F();}// 8.0usingFontf2newFont(黑体,12FontStyle.Blod);f2.F()C#8.0后简化了使用可以避免嵌套。在声明变量时如果类型实现了IDisposable或IAsyncDisposable接口那么可以在变量声明前加上using关键字这样当代码执行离开被using修饰的变量作用域时变量只想的对象的Dispose方法就会被调用。》》》readonlypublicreadonlystructPerson{publicstringName{get;}publicstringSurname{get;}publicintAge{get;}publicPerson(stringname,stringsurname,intage){Namename;Surnamesurname;Ageage;}}官网C# 7.3》》inC# 7.2》》 命名参数、具名参数》》》 条件 ref 表达式C# 7.1》》 default 运算符default 在C#7.1中得到了改进不再需要defaultT了//变量赋值C#7.0vars字符串;sdefault(string);C#7.1vars字符串;sdefault;//初始化赋值C#7.0vardstringdefault(string);vardintdefault(int);vardintNulldefault(int?);varddefault(dynamic);vardtdefault(DateTime);vardt1default(DateTime?);C#7.1stringsdefault;intidefault;DateTime?dtdefault;dynamicddefault;//可选参数C#7.0voidTest(inta,stringbdefault(string)){}C#7.1voidTest(inta,stringbdefault){}》》》 元组功能提供了简洁的语法来将多个数据元素分组成一个轻型数据结构。(double,int)t1(4.5,3);Console.WriteLine($Tuple with elements{t1.Item1}and{t1.Item2}.);// Output:// Tuple with elements 4.5 and 3.(doubleSum,intCount)t2(4.5,3);Console.WriteLine($Sum of{t2.Count}elements is{t2.Sum}.);// Output:// Sum of 3 elements is 4.5.C# 7.0》》类型模式》》格式expr is type varname varname 是类型匹配后赋值的变量名称。》》常量模式描述用于测试表达式计算结果是否为指定的常数值。格式expr is constant,constant 的可以是下面的表达式文字值。一个枚举常量。已声明 const 变量的名称。》》var 模式 跟 》》类型模式 一样描述始终匹配成功可将表达式的值绑定到新局部变量。格式expr is var varname如果 expr 为 null is 表达式也为 true varname 为 null。staticIEnumerableintFactor(intnumber){intmax(int)Math.Sqrt(number);for(inti1;imax;i){if(number%i0){yieldreturni;if(i!number/i){yieldreturnnumber/i;}}}}int[]testSet{22,33,44,55};varprimestestSet.Where(nFactor(n).ToList()isvarfactorsfactors.Count2factors.Contains(1)factors.Contains(n));》》》Swith 模式匹配inta10;stringresultaswitch//a用来匹配符合的值返回给result{1老鼠,//匹配值的数据类型要和a的数据类型一致后面的内容就是要赋值给result的内容result的类型要匹配2黄牛,//每条结束要用隔开3白虎,_青龙//_下划线表示弃元模式兜底作用};Console.WriteLine(result);Console.Write(请输入学生成绩);intscoreConvert.ToInt32(Console.ReadLine());stringresultscoreswitch{90优秀,//90可以理解成大于等于90的某个数这样就不会违反switch使用规则当有多个条件时可以使用and or 来链接60良好,_不及格};Console.WriteLine(result);publicStatePerformOperation(stringcommand)commandswitch{SystemTestRunDiagnostics(),StartStartSystem(),StopStopSystem(),ResetResetToReady(),_thrownewArgumentException(Invalid string value for command,nameof(command)),};》》》Out 关键字可以在out后面直接声明变量例如前TryParse需要先定义再使用的两行的代码现在一行即可 int.TryParse(s, out int num)从而简化语法。》》 Tuples 元组元组改进可以为无组添加名称用法方式1定义(int one, int two) tuple (1, 2); 使用 WriteLine( f i r s t t u p l e . o n e , s e c o n d t u p l e . t w o ) ; 。方式 2 定义 v a r t u p l e 2 ( o n e : 1 , t w o : 2 ) ; 使用 W r i t e L i n e ( first{tuple.one}, second{tuple.two});。 方式2定义var tuple2 (one: 1, two: 2); 使用 WriteLine(firsttuple.one,secondtuple.two);。方式2定义vartuple2(one:1,two:2);使用WriteLine(“first{tuple2.one}, second{tuple2.two}”);。》》》本地方法》》 Ref 局部变量 返回引用对ref引用进行了加强现在可以引用一个方法中的局部变量语法是在方法定义前加上 ref同时在返回时也加上ref如定义函数refintGetDataRef(int[]data,intindex){returnrefdata[index];}refintnumrefGetDataRef(newdata[]{1,2,3},0);则 ref int num ref GetDataRef(new data[]{1,2,3}, 0); 返回对数组中第0个元素的引用。则 int num GetDataRef(new data[]{1,2,3}, 0); 返回对数组中第0个元素的值。》》 throw 之前都说手动抛出异常C# 7.0 引入了throw表达式它允许我们在条件表达式中抛出异常。官方的解析说这对提高代码可读性有利。如》》》 数字文本语法改进 这个一般上位机用比较多C# 6.0》》Import of static type members into namespace用于简化书写。在引用类名后可以直接使用类的静态成员比如在使用 using static System.String; 后可以将 String.IsNullOrEmpty(str) 可以直接写成 IsNullOrEmpty(str)。案例l》》只读自动属性只读自动属性提供了更简洁的语法来创建不可变类型。 你声明仅具有 get 访问器的自动属性public string FirstName { get; }public string LastName { get; }FirstName 和 LastName 属性只能在构造函数的主体中设置》》 自动属性初始化表达式自动属性初始值设定项可让你在属性声明中声明自动属性的初始值。public class Student{public string FirstName { get; } “xxx”;public string LastName { get; private set; } “tttt”;}FirstName,LaseName 成员在声明它的位置处被初始化。 这样就能更容易地仅执行一次初始化。 初始化是属性声明的一部分可更轻松地将存储分配。//之前版本publicstringGetInfo(){returnzen;}// 6.0 版本publicstringGetInfo()“zen”;》》 Expression-bodied(正文表达式) 函数成员你编写的许多成员是可以作为单个表达式的单个语句。 改为编写 expression-bodied 成员。这适用于方法和只读属性。在 C# 7.0 中你可以在属性 和索引器 上实现构造函数 、终结器 以及 get 和 set 访问器例如重写 ToString() 通常是理想之选public override string ToString() $“{LastName}, {FirstName}”;也可以将此语法用于只读属性public string FullName $“{FirstName} {LastName}”;》》Null 条件运算符 断路运算符 Null 条件运算符使 null 检查更轻松、更流畅。 将成员访问 . 替换为 ?.var first person?.FirstName;在前面的示例中如果 Person 对象是 null则将变量 first 赋值为 null。 否则将 FirstName 属性的值分配给该变量。最重要的是?. 意味着当 person 变量为 null 时此行代码不会生成 NullReferenceException。它会短路并返回 null。 还可以将 null 条件运算符用于数组或索引器访问。将索引表达式中的 [] 替换为 ?[]。first person?.FirstName ?? “Unspecified”; //?? a??b 当a为null时则返回ba不为null时则返回a本身。》》字符串内插使用 C# 6新的字符串内插功能可以在字符串中嵌入表达式。使用 $ 作为字符串的开头并使用 { 和 } 之间的表达式代替序号public string FullName $“{FirstName} {LastName}”;》》异常筛选器try{doSomething();}catch(Exceptione)when(e.Message.Contains(xx)){ProcessException(e);}//等价于catch(Exceptione){if(e.Message.Contains(xx))// 如果判断的逻辑较多建议使用该方式。{returnSite Moved;}}》》 nameofNameof是一个运算符用于获取代码元素如变量、类和方法等的名称是的字符串。它通过将名称作为字符串文字返回来帮助您密切关注名称int myInt 10;Console.WriteLine(nameof(myInt)); // Output: “myInt”》》索引器初始化关联集合 C# 3.0 集合初始化器
返回列表