引用:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-version-history
7.0-7.3
元组和弃元
(string Alpha, string Beta) namedLetters = ("a", "b");
Console.WriteLine($"{namedLetters.Alpha}, {namedLetters.Beta}");
var alphabetStart = (Alpha: "a", Beta: "b");
Console.WriteLine($"{alphabetStart.Alpha}, {alphabetStart.Beta}");
模式匹配
public static int SumPositiveNumbers(IEnumerable<object> sequence)
{
int sum = 0;
foreach (var i in sequence)
{
switch (i)
{
case 0:
break;
case IEnumerable<int> childSequence:
{
foreach(var item in childSequence)
sum += (item > 0) ? item : 0;
break;
}
case int n when n > 0:
sum += n;
break;
case null:
throw new NullReferenceException("Null found in sequence");
default:
throw new InvalidOperationException("Unrecognized type");
}
}
return sum;
}
case 0:
是常见的常量模式。case IEnumerable<int> childSequence:
是一种类型模式。case int n when n > 0:
是具有附加when
条件的类型模式。case null:
是 null 模式。default:
是常见的默认事例。
异步 main
方法
static async Task<int> Main()
{
// This could also be replaced with the body
// DoAsyncWork, including its await expressions:
return await DoAsyncWork();
}
static async Task Main()
{
await SomeAsyncMethod();
}
本地函数
public static IEnumerable<char> AlphabetSubset3(char start, char end)
{
return alphabetSubsetImplementation();
IEnumerable<char> alphabetSubsetImplementation()
{
for (var c = start; c < end; c++)
yield return c;
}
}
确认的特性
public void DoProcessing()
{
TraceMessage("Something happened.");
}
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
Trace.WriteLine("message: " + message);
Trace.WriteLine("member name: " + memberName);
Trace.WriteLine("source file path: " + sourceFilePath);
Trace.WriteLine("source line number: " + sourceLineNumber);
}
// Sample Output:
// message: Something happened.
// member name: DoProcessing
// source file path: c:\Visual Studio Projects\CallerInfoCS\CallerInfoCS\Form1.cs
// source line number: 31
expression-bodied
// Expression-bodied constructor
public ExpressionMembersExample(string label) => this.Label = label;
private string label;
// Expression-bodied get / set accessors.
public string Label
{
get => label;
set => this.label = value ?? "Default label";
}
默认文本表达式
Func<string, bool> whereClause = default;
T[] InitializeArray<T>(int length, T initialValue = default)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length), "Array length must be nonnegative.");
}
var array = new T[length];
for (var i = 0; i < length; i++)
{
array[i] = initialValue;
}
return array;
}
void Display<T>(T[] values) => Console.WriteLine($"[ {string.Join(", ", values)} ]");
Display(InitializeArray<int>(3)); // output: [ 0, 0, 0 ]
Display(InitializeArray<bool>(4, default)); // output: [ False, False, False, False ]
System.Numerics.Complex fillValue = default;
Display(InitializeArray(3, fillValue)); // output: [ (0, 0), (0, 0), (0, 0) ]
数字文本语法改进
二进制文本和数字分隔符
public const int Sixteen = 0b0001_0000;
public const int ThirtyTwo = 0b0010_0000;
public const int SixtyFour = 0b0100_0000;
public const int OneHundredTwentyEight = 0b1000_0000;
public const long BillionsAndBillions = 100_000_000_000;
public const double AvogadroConstant = 6.022_140_857_747_474e23;
public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
out
变量
if (int.TryParse(input, out var answer))
Console.WriteLine(answer);
else
Console.WriteLine("Could not parse input");
命名实参
PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);
private protected 访问修饰符
protected internal
允许通过同一程序集中的类或派生类进行访问,private protected
限制对同一程序集中声明的派生类的访问
in
参数修饰符
ref引用可修改,out强制修改,in引用只读
通用的异步返回类型
public async ValueTask<int> Func()
{
await Task.Delay(100);
return 5;
}