00C#新版本语法
一、C#5.0
版本:VS2012
1、异步成员 async await
public Task Show() { return Task.FromResult(0); } public async Task ShowAsync() { await Task.FromResult(0); }
2、调用者特性
public void DoProcessing() { TraceMessage("Something happened. DoProcessing"); } public void DoProcessingNew() { TraceMessage("Something happened. DoProcessingNew"); } public void TraceMessage(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { Console.WriteLine("message: " + message); Console.WriteLine("member name: " + memberName); Console.WriteLine("source file path: " + sourceFilePath); Console.WriteLine("source line number: " + sourceLineNumber); //调用本方法,是哪个类中是哪个方法中的的第几行代码来调用本方法; }
二、C#6.0
版本:VS2015
1、静态导入using
using static CSharpDemo.CSharp6.StudentServie; //1、引入带有静态成员的类 using static CSharpDemo.CSharp6.Color; //2、引入枚举 using sharp5 = CSharpDemo.CSharp5; //3、给命名空间来一个别名 using Sharp6genericeInt = CSharpDemo.CSharp6.GenericClass<int>;
2、异常筛选器
try { ShowExceptionType(); } catch (Exception e) when (e.Message.Contains("002")) //异常筛选器 { Console.WriteLine("这里是处理捕捉到的002的异常~"); }、
3、自动属性初始化表达式
public static int Id { get; set; } = 123445678;
4、字符串内插
string text = "欢迎来到.NET 高级班进阶学习~"; string hello1 = $"你好:{text}";
5、Null 传播器
sharp5.UserInfo? user1 = null; var userName1 = user1?.Name;
6、nameof 运算符
Console.WriteLine(nameof(System.Collections.Generic)); // output: Generic Console.WriteLine(nameof(List<int>)); // output: List Console.WriteLine(nameof(List<int>.Count)); // output: Count Console.WriteLine(nameof(List<int>.Add)); // output: Add var numbers = new List<int> { 1, 2, 3 }; Console.WriteLine(nameof(numbers)); // output: numbers Console.WriteLine(nameof(numbers.Count)); // output: Count Console.WriteLine(nameof(numbers.Add)); // output: Add
三、C#7.0
版本:VS2017
1、out变量
var input = "123456"; //int result;旧写法 if (int.TryParse(input, out var result)) //新写法 { Console.WriteLine("您输入的数字是:{0}", result); } else { Console.WriteLine("无法解析输入..."); }
2、元祖和析构函数
//元组简单化 { Tuple<double, int> ttext = new Tuple<double, int>(123, 234); (double, int) t1 = (4.5, 3); Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}."); // Output: // Tuple with elements 4.5 and 3. (double Sum, int Count) t2 = (4.5, 3); Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}."); } //元组的用例 { var xs = new[] { 4, 7, 9 }; var limits = FindMinMax(xs); Console.WriteLine($"Limits of [{string.Join(" ", xs)}] are {limits.min} and {limits.max}"); // Output: // Limits of [4 7 9] are 4 and 9 var ys = new[] { -9, 0, 67, 100 }; var (minimum, maximum) = FindMinMax(ys); Console.WriteLine($"Limits of [{string.Join(" ", ys)}] are {minimum} and {maximum}"); } //元组字段名称 { var t = (Sum: 4.5, Count: 3); Console.WriteLine($"Sum of {t.Count} elements is {t.Sum}."); (double Sum, int Count) d = (4.5, 3); Console.WriteLine($"Sum of {d.Count} elements is {d.Sum}."); } //元祖取值 { var a = 1; var t = (a, b: 2, 3); Console.WriteLine($"The 1st element is {t.Item1} (same as {t.a})."); Console.WriteLine($"The 2nd element is {t.Item2} (same as {t.b})."); Console.WriteLine($"The 3rd element is {t.Item3}."); } //元组赋值和析构 { (int, double) t1 = (17, 3.14); (double First, double Second) t2 = (0.0, 1.0); t2 = t1; Console.WriteLine($"{nameof(t2)}: {t2.First} and {t2.Second}"); // Output: // t2: 17 and 3.14 (double A, double B) t3 = (2.0, 3.0); t3 = t2; Console.WriteLine($"{nameof(t3)}: {t3.A} and {t3.B}"); // Output: // t3: 17 and 3.14 } //在括号内显式声明每个变量的类型: { var t = ("post office", 3.6); (string destination, double distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers. } //在括号外使用 var 关键字来声明隐式类型化变量,并让编译器推断其类型: { var t = ("post office", 3.6); var (destination, distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers. } //使用现有变量: { var destination = string.Empty; var distance = 0.0; var t = ("post office", 3.6); (destination, distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers. } //元组相等 { (int a, byte b) left = (5, 10); (long a, int b) right = (5, 10); Console.WriteLine(left == right); // output: True Console.WriteLine(left != right); // output: False var t1 = (A: 5, B: 10); var t2 = (B: 5, A: 10); Console.WriteLine(t1 == t2); // output: True Console.WriteLine(t1 != t2); // output: False } //元组作为 out 参数 { var limitsLookup = new Dictionary<int, (int Min, int Max)>() { [2] = (4, 10), [4] = (10, 20), [6] = (0, 23) }; if (limitsLookup.TryGetValue(4, out (int Min, int Max) limits)) { Console.WriteLine($"Found limits: min is {limits.Min}, max is {limits.Max}"); } // Output: // Found limits: min is 10, max is 20 }
3、模糊匹配
//Null 检查 { int? maybe = 12; if (maybe is int number) { Console.WriteLine($"The nullable int 'maybe' has the value {number}"); } else { Console.WriteLine("The nullable int 'maybe' doesn't hold a value"); } string? message = "This is not the null string"; if (message is not null) { Console.WriteLine(message); } }
//类型测试 public static T MidPoint<T>(IEnumerable<T> sequence) { if (sequence is IList<T> list) { return list[list.Count / 2]; } else if (sequence is null) { throw new ArgumentNullException(nameof(sequence), "Sequence can't be null."); } else { int halfLength = sequence.Count() / 2 - 1; if (halfLength < 0) halfLength = 0; return sequence.Skip(halfLength).First(); } }
//比较离散值 public static string PerformOperation(string command) => command switch { "SystemTest" => "SystemTest", "Start" => "Start", "Stop" => "Stop", "Reset" => "Reset", _ => throw new ArgumentException("Invalid string value for command", nameof(command)), };
//关系模式 public static string WaterState(int tempInFahrenheit) => tempInFahrenheit switch { (> 32) and (< 212) => "liquid", < 32 => "solid", > 212 => "gas", 32 => "solid/liquid transition", 212 => "liquid / gas transition", };
4、本地函数
SayHello("你好~"); string SayHello(string hello) { Console.WriteLine(hello); return hello; }
5、弃元与命名参数
//弃元 var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010); //命名参数 QueryCityDataForYears(year1: 2022, year2: 2021, name: "Richard");
6、Ref局部变量和返回结果
int[] a = { 0, 1, 2, 3, 4, 5 }; // x不是一个引用,函数将值赋值给左侧变量x int x = GetLast(a); Console.WriteLine("======================================================================"); Console.WriteLine($"x:{x}, a[2]:{a[a.Length - 1]}"); x = 99; Console.WriteLine("======================================================================"); Console.WriteLine($"x:{x}, a[2]:{a[a.Length - 1]} \n"); // 返回引用,需要使用ref关键字,y是一个引用,指向a[a.Lenght-1] ref int y = ref GetLast(a); Console.WriteLine("======================================================================"); Console.WriteLine($"y:{y}, a[2]:{a[a.Length - 1]}"); y = 100; Console.WriteLine("======================================================================"); Console.WriteLine($"y:{y}, a[2]:{a[a.Length - 1]}");
四、C#8.0
版本: C# 8.0 版是专门面向 .NET C# Core 的第一个主要 C# 版本
1、默认接口方法
public interface IStudent { public int GetAge(); public string GetName() { return "张三同学"; } }
2、Switch表达式
/// <summary> /// Switch模式 /// </summary> /// <param name="colorBand"></param> /// <returns></returns> /// <exception cref="ArgumentException"></exception> public static Rainbow FromRainbow(Rainbow colorBand) => colorBand switch { Rainbow.Red => Rainbow.Red, Rainbow.Orange => Rainbow.Orange, Rainbow.Yellow => Rainbow.Yellow, Rainbow.Green => Rainbow.Green, Rainbow.Blue => Rainbow.Blue, Rainbow.Indigo => Rainbow.Indigo, Rainbow.Violet => Rainbow.Violet, _ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)), };
3、属性模式
/// <summary> /// 属性模式 /// </summary> /// <param name="location"></param> /// <param name="salePrice"></param> /// <returns></returns> 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, _ => 0M };
4、元祖模式
/// <summary> /// 元组模式 /// </summary> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static string RockPaperScissors(string first, string second) => (first, second) switch { ("rock", "paper") => "rock is covered by paper. Paper wins.", ("rock", "scissors") => "rock breaks scissors. Rock wins.", ("paper", "rock") => "paper covers rock. Paper wins.", ("paper", "scissors") => "paper is cut by scissors. Scissors wins.", ("scissors", "rock") => "scissors is broken by rock. Rock wins.", ("scissors", "paper") => "scissors cuts paper. Scissors wins.", (_, _) => "tie" };
5、位置模式
/// <summary> /// 位置模式 /// </summary> /// <param name="point"></param> /// <returns></returns> public static Quadrant GetQuadrant(Point point) => point switch { (0, 0) => Quadrant.Origin, var (x, y) when x > 0 && y > 0 => Quadrant.One, var (x, y) when x < 0 && y > 0 => Quadrant.Two, var (x, y) when x < 0 && y < 0 => Quadrant.Three, var (x, y) when x > 0 && y < 0 => Quadrant.Four, var (_, _) => Quadrant.OnBorder, };
6、Using模式
/// <summary> /// using声明--新版本 /// </summary> /// <param name="lines"></param> /// <returns></returns> public static int WriteLinesToFileNew(IEnumerable<string> lines) { using var file = new System.IO.StreamWriter("WriteLines2.txt"); //新写法 int skippedLines = 0; foreach (string line in lines) { if (!line.Contains("Second")) { file.WriteLine(line); } else { skippedLines++; } } // Notice how skippedLines is in scope here. return skippedLines; // file is disposed here }
7、静态本地函数
M(); static int M() { int y = 5; int x = 7; return Add(x, y); static int Add(int left, int right) => left + right; }
8、可处置单Ref结构
public ref struct UserStruct //: IDisposable { public int Id { get; set; } public string? Name { get; set; } //public void Dispose() //{ // throw new NotImplementedException(); //} }
9、可为空单引用类型
string? name = "Richard老师"; Student? student = null;
10、异步流
/// <summary> /// 异步流支持 /// </summary> /// <returns></returns> public static async IAsyncEnumerable<int> GetNewAsyncIntList() { for (int i = 0; i < 20; i++) { await Task.Delay(100); yield return i; } } /// <summary> /// 异步流支持 /// </summary> /// <returns></returns> public static async Task GetAsyncData() { await foreach (var number in GetNewAsyncIntList()) { Console.WriteLine(number); } }
11、索引和范围
string[] words = new string[] { // index from start index from end "The", // 0 ^9 "quick", // 1 ^8 "brown", // 2 ^7 "fox", // 3 ^6 "jumped", // 4 ^5 "over", // 5 ^4 "the", // 6 ^3 "lazy", // 7 ^2 "dog" // 8 ^1 }; string message1 = words[0]; string message2 = words[1]; var quickBrownFox = words[1..4]; string message3 = words[^1]; string message4 = words[^2]; var lazyDog = words[^2..^0]; var allWords = words[..]; // contains "The" through "dog". var firstPhrase = words[..4]; // contains "The" through "fox" var lastPhrase = words[6..]; // contains "the", "lazy" and "dog" //声明范围 Range phrase = 1..4; var text = words[phrase]; //使用范围
12、Null合并赋值
List<int> numbers = null; int? i = null; numbers ??= new List<int>(); numbers.Add(i ??= 17); numbers.Add(i ??= 20); Console.WriteLine(string.Join(" ", numbers)); // output: 17 17 Console.WriteLine(i); // output: 17 numbers ??= new List<int>() { 123, 234, 345, 456, 567, 678 };
13、内插逐字字符串的增强功能,$和@不分前后顺序了,在早期,$必须在@前面
string text = "HelloWord"; string text1 = $@"欢迎大家,{text}"; string text2 = @$"欢迎大家,{text}";
五、C#9.0
版本:跟.Net5 一起发布
1、记录
//1、不可变性: Person1 person = new Person1("Richard老师", "金牌讲师Richard"); Console.WriteLine($"person.FirstName={person.FirstName}"); Console.WriteLine($"person.LastName={person.LastName}"); person.Deconstruct(out string firstName, out string lastname); Console.WriteLine($"person.FirstName={firstName}"); Console.WriteLine($"person.LastName={lastname}"); //person.FirstName = "SDGWRWT"; //不能重新赋值 Console.WriteLine("=================================================="); //不可变性: Person2 personInfo = new Person2() { FirstName = "Richard老师", LastName = "金牌讲师Richard" }; Console.WriteLine($"personInfo.FirstName={personInfo.FirstName}"); Console.WriteLine($"personInfo.LastName={personInfo.LastName}"); //personInfo.FirstName = "SDGWRWT"; //不能重新赋值 Console.WriteLine("=================================================="); //2、可变 Person3 personNew = new Person3() { FirstName = "Richard老师", LastName = "金牌讲师Richard" }; Console.WriteLine($"personNew.FirstName={personNew.FirstName}"); Console.WriteLine($"personNew.LastName={personNew.LastName}"); personNew.FirstName = "SDGWRWT"; //可以重新赋值 Console.WriteLine($"personNew.FirstName={personNew.FirstName}"); } //3、值相等性 { var phoneNumbers = new string[2]; Person4 person1 = new("Nancy", "Davolio", phoneNumbers); Person4 person2 = new("Nancy", "Davolio", phoneNumbers); Console.WriteLine(person1 == person2); // output: True person1.PhoneNumbers[0] = "555-1234"; Console.WriteLine(person1 == person2); // output: True Console.WriteLine(ReferenceEquals(person1, person2)); // output: False } //4、非破坏性变化 { Person5 person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] }; Console.WriteLine(person1); // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] } Person5 person2 = person1 with { FirstName = "John" }; Console.WriteLine(person2); // output: Person { FirstName = John, LastName = Davolio, PhoneNumbers = System.String[] } Console.WriteLine(person1 == person2); // output: False person2 = person1 with { PhoneNumbers = new string[1] }; Console.WriteLine(person2); // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] } Console.WriteLine(person1 == person2); // output: False person2 = person1 with { }; Console.WriteLine(person1 == person2); // output: True // 用于显示的内置格式设置 Console.WriteLine($"显示的内置格式:{person1.ToString()}"); } //5、继承 //条记录可以从另一条记录继承。 但是,记录不能从类继承,类也不能从记录继承。 { Person6 teacher = new Teacher("Nancy", "Davolio", 3); Console.WriteLine(teacher); // output: Teacher { FirstName = Nancy, LastName = Davolio, Grade = 3 } } //要使两个记录变量相等,运行时类型必须相等。 包含变量的类型可能不同。 下面的代码示例中说明了这一点: { Person6 teacher = new Teacher("Nancy", "Davolio", 3); Person6 student = new Student1("Nancy", "Davolio", 3); Console.WriteLine(teacher == student); // output: False Person6 student2 = new Student1("Nancy", "Davolio", 3); Console.WriteLine(student2 == student); // output: True //派生类型和基类型的所有公共属性和字段都包含在 ToString 输出中,如以下示例所示: Console.WriteLine(teacher.ToString()); Console.WriteLine(student.ToString()); Console.WriteLine(student2.ToString()); }
2、仅限Init的资源库
var now = new WeatherObservation { RecordedAt = DateTime.Now, TemperatureInCelsius = 20, PressureInMillibars = 998.0m }; //now.TemperatureInCelsius = 18; 不允许--必须在初始化的时候赋值,后续就不允许修改了
3、顶级语句
//顶级语句 - 不使用 Main 方法的程序 //最明显的案例就是控制台直接撸码 //只有一行代码执行所有操作。 借助顶级语句,可使用 using 指令和执行操作的一行替换所有样本:
4、模式匹配增强功能
//C# 9 包括新的模式匹配改进: //类型模式 与对象匹配特定类型 //带圆括号的模式强制或强调模式组合的优先级 //联合 and 模式要求两个模式都匹配 //析取 or 模式要求任一模式匹配 //否定 not 模式要求模式不匹配 //关系模式要求输入小于、大于、小于等于或大于等于给定常数。 bool bResult = Extension.IsLetter('1'); bool bResult1 = Extension.IsLetterOrSeparator('C'); public static class Extension { public static bool IsLetter(this char c) => c is >= 'a' and <= 'z' or >= 'A' and <= 'Z'; public static bool IsLetterOrSeparator(this char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ','; }
5、目标类型的new表达式
List<WeatherObservation> _observations = new(); WeatherStation station = new() { Location = "Seattle, WA" }; station.ForecastFor(DateTime.Now.AddDays(2), new());
6、静态匿名函数
Func<int, bool> func = static i => { return true; }; func.Invoke(123);
7、扩展GetEnumerator支持foreach循环
Person[] PersonList = new Person[3] { new ("John", "Smith"), new ("Jim", "Johnson"), new ("Sue", "Rabon"), }; People people = new People(PersonList); foreach (var person in people) { Console.WriteLine(person); } public static class PeopleExtensions { //public static IEnumerator<T> GetEnumerator<T>(this IEnumerator<T> people) => people; public static People GetEnumerator(this People people) => people; }
8、Lambda弃元参数
// C# 9 之前 Func<int, int, int> zero = (a, b) => 0; Func<int, int, int> func = delegate (int a, int b) { return 0; }; // C# 9 Func<int, int, int> zero1 = (_, _) => 0; Func<int, int, int> func2 = delegate (int _, int _) { return 0; };
9、扩展分部方法
public partial class User { public partial void Show(string message); } public partial class User { public partial void Show(string message) => Console.WriteLine(message); }
六、C#10.0
1、记录结构
/// <summary> /// 普通方式声明结构 /// </summary> public struct PersonStruct { public string Name { get; init; } public int Age { get; init; } public Gender Gender { get; init; } } // Use record struct. /// <summary> /// 结构记录类型 /// </summary> /// <param name="Name"></param> /// <param name="Age"></param> /// <param name="Gender"></param> public record struct PersonNewStruct(string Name, int Age, Gender Gender);
PersonStruct person = new PersonStruct() { Age = 36, Gender = Gender.Male, Name = "老师" }; //person.Age = 40; //不允许 PersonNewStruct personNewStruct = new PersonNewStruct() { Age = 36, Name = "老师", Gender = Gender.Male, }; personNewStruct.Age = 40; //允许 personNewStruct.Deconstruct(out string name, out int age, out Gender gender); Console.WriteLine($"personNewStruct.name={name}"); Console.WriteLine($"personNewStruct.age={age}"); Console.WriteLine($"personNewStruct.gender={gender}"); //with表达式--得到一个结构的副本 { PersonNewStruct personNew = personNewStruct with { Name = "Sunnie" }; Console.WriteLine($"personNew.Name={personNew.Name}"); Console.WriteLine($"personNewStruct.gender={gender}"); }
2、结构类型的改进
/// <summary> /// 定义结构构造函数 /// </summary> record struct PersonInfo01() { public object Id { get; init; } = 123; public object Name { get; init; } = "老师"; } record struct PersonInfo02(string name) { public object Id { get; init; } = 123; public object Name { get; init; } = name; } record struct PersonInfo03 { //构造函数必须使用public修饰 public PersonInfo03() { Assembly assembly = Assembly.LoadFrom("Zhaoxi.CSharpDemo.dll"); } //构造函数必须使用public修饰 public PersonInfo03(string name) { Name = name; } public object? Id { get; init; } = 123; public object? Name { get; init; } = "老师"; }
//无参构造函数 PersonInfo01 person = new PersonInfo01(); Console.WriteLine($"person.Id={person.Id}"); Console.WriteLine($"person.Name={person.Name}"); //传参构造函数 PersonInfo02 person2 = new PersonInfo02("老师"); Console.WriteLine($"person2.Id={person2.Id}"); Console.WriteLine($"person2.Name={person2.Name}"); //调用默认无参构造函数 PersonInfo02 personNoCtor = new PersonInfo02(); Console.WriteLine($"personNoCtor.Id={personNoCtor.Id}"); Console.WriteLine($"personNoCtor.Name={personNoCtor.Name}"); //调用无参构造函数 PersonInfo03 personInfo03 = new PersonInfo03(); Console.WriteLine($"personInfo03.Id={personInfo03.Id}"); Console.WriteLine($"personInfo03.Name={personInfo03.Name}"); //调用有参构造函数 PersonInfo03 personInfoNew = new PersonInfo03("老师"); Console.WriteLine($"personInfoNew.Id={personInfoNew.Id}"); Console.WriteLine($"personInfoNew.Name={personInfoNew.Name}");
3、全局使用using指令
例如: global using static System.Reflection.Assembly; global using System.Reflection; //隐式usings //隐式usings功能会自动在构建的项目类型添加通用的全局using指令。 //要启用隐式usings,请在.csproj 文件中设置 ImplicitUsings 属性: <ImplicitUsings>enable</ImplicitUsings>
5、文件范围的命名空间声明
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyNamespace; class Class1 { }
6、扩展属性模式
object obj = new UserInfo { UserId = 123, UserName = "Richard老师", Age = 36, Address = new CSharp10.Address() { City = "WuHan" } }; if (obj is UserInfo { Address: { City: "WuHan" } }) { Console.WriteLine("WuHan"); } if (obj is UserInfo { Address.City: "WuHan" }) // Extended property pattern { Console.WriteLine("WuHan"); }
7、对Lambda表达式的改进
//Lambda标记特性 { var f1 = [TestAttribute] () => { }; // [A] lambda var method = f1.GetMethodInfo(); TestAttribute attribute = method.GetCustomAttribute<TestAttribute>(); attribute.Show(); } //Lambda标记特性 静态修饰 { var f2 = [TestAttribute] static (int x) => x; // syntax error at '=>' var method = f2.GetMethodInfo(); TestAttribute attribute = method.GetCustomAttribute<TestAttribute>(); attribute.Show(); } //Lambda标记特性修饰返回值 { var f3 = [return: TestAttribute] (int x) => x; // syntax error at '=>' ICustomAttributeProvider provider = f3.GetMethodInfo().ReturnTypeCustomAttributes; object[] attributeArray = provider.GetCustomAttributes(typeof(TestAttribute), true); foreach (TestAttribute attribute in attributeArray) { attribute.Show(); } } //Lambda标记特性修饰参数 { var f4 = ([TestAttribute] int x) => x; // [A] x ParameterInfo[] prarArray = f4.GetMethodInfo().GetParameters(); foreach (var para in prarArray) { TestAttribute attribute = para.GetCustomAttribute<TestAttribute>(); attribute.Show(); } } //Lambda标记特性修饰参数 { var f5 = ([TestAttribute] ref int x) => x; // [A] x ParameterInfo[] prarArray = f5.GetMethodInfo().GetParameters(); foreach (var para in prarArray) { TestAttribute attribute = para.GetCustomAttribute<TestAttribute>(); attribute.Show(); } }
8、可使用const内插字符串
const string Language = "C#"; const string Platform = ".NET"; const string Version = "10.0"; const string FullProductName = $"{Platform} - Language: {Language} Version: {Version}";
9、记录类型可密封ToString()
public record Person(string FirstName, string LastName); public record PersonChild(string FirstName, string LastName) : Person(FirstName, LastName) { /// <summary> /// 如果再有某一个记录,继承自本记录,则T本记录,则ToString不可用 /// </summary> /// <returns></returns> public sealed override string ToString() { return base.ToString(); } }
10、对Lambda支持关键字
var f = ref int (ref int x) => ref x;