大家好,欢迎来到IT知识分享网。
系列文章
C#8.0特性(一)
C#8.0特性(二)
内联申明out变量
在7.0以前我们遇到使用带有out参数的方法时需要单独申明这个变量,在7.0以后可以内联的使用out变量
Int32 result;
Int32.TryParse(input, out result); // use out variable in c#6.0
Int32.TryParse(input, out Int32 result); // use out variable in c#7.0+
Int32.TryParse(input, out var result); // use implicitly out variable in c#7.0+
元组
C# 为用于说明设计意图的类和结构提供了丰富的语法。但是有时候这种语法很笨重;在7.0以前c#也提供元组,当不是语言级别的支持
元组是包含多个字段以表示数据成员的轻量级数据结构。 这些字段没有经过验证,并且你无法定义自己的方法
(string Alpha, string Beta) namedLetters = ("a", "b"); // use Tuples in c#7.0+
Console.WriteLine(#34;{namedLetters.Alpha}, {namedLetters.Beta}");
弃元
在使用具有out参数的方法调用时,或者元组析构时,有时候必须为了不需要使用的参数或者元素定义一个变量,在c#7.0可以通过使用名为 _(下划线) 的符号来放弃指定位置的值;
弃元可以使用在1)元素或用户自定义类型解构,2)调用具有out参数的方法,3)is或者swith的模式匹配语句中,4)赋值语句的左值
在对元组或用户定义的类型进行解构时。
在使用 out 参数调用方法时。
在使用 is 和 switch 语句匹配操作的模式中。
在要将某赋值的值显式标识为弃元时用作独立标识符。
模式匹配
模式匹配支持 is 表达式和 switch 表达式。
// is 增强的模式匹配
if (input is int count) // 经过测试后将值赋给后面类型正确的新变量
sum += count;
// switch 模式匹配
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: // 具有附加 when 条件的类型模式
sum += n;
break;
case null: // null 模式
throw new NullReferenceException("Null found in sequence");
default: // 常见的默认事例
throw new InvalidOperationException("Unrecognized type");
}
}
return sum;
}
ref 局部变量和返回结果
允许返回和使用在其它地方定义的引用变量
// Demo 在一个矩阵中查找指定元素并返回其引用
public static ref int Find(int[,] matrix, Func<int, bool> predicate)
{
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
if (predicate(matrix[i, j]))
return ref matrix[i, j];
throw new InvalidOperationException("Not found");
}
本地函数
许多类的设计都包括仅从一个位置调用的方法。 这些额外的私有方法使每个方法保持小且集中。
// Demo 通过本地函数使得方法中参数检验肯执行分离
public static IEnumerable<char> AlphabetSubset3(char start, char end)
{
if (start < 'a' || start > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
if (end < 'a' || end > 'z')
throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");
if (end <= start)
throw new ArgumentException(#34;{nameof(end)} must be greater than {nameof(start)}");
return alphabetSubsetImplementation();
IEnumerable<char> alphabetSubsetImplementation()
{
for (var c = start; c < end; c++)
yield return c;
}
}
expression-bodied 成员
在c# 6.0中只为只读属性和成员函数引入了表达式体,在c# 7.0 扩展到可在属性,索引器,终结器,get,set访问器使用
// Expression-bodied constructor
public ExpressionMembersExample(string label) => this.Label = label;
// Expression-bodied finalizer
~ExpressionMembersExample() => Console.Error.WriteLine("Finalized!");
private string label;
// Expression-bodied get / set accessors.
public string Label
{
get => label;
set => this.label = value ?? "Default label";
}
throw 表达式
在c# 7.0以前 throw 不可以在三元表达式 ?? 表达式 以及表达式体中出现,下面演示在三元表达式中使用throw表达式
// use throw expression in condational opeartor, you must appear in an if/else statement.1
string arg = args.Length >= 1 ? args[0] : throw new ArgumentException("You must supply an argument");
通用的异步返回类型
从异步方法返回 Task 对象可能在某些路径中导致性能瓶颈。 Task 是引用类型,因此使用它意味着分配对象。 如果使用 async 修饰符声明的方法返回缓存结果或以同步方式完成,那么额外的分配在代码的性能关键部分可能要耗费相当长的时间。 如果这些分配发生在紧凑循环中,则成本会变高。
新的特性去除了异步方法必须从Task,Task<T>, void 返回,只要返回值具有可以访问的GetAwaiter方法即可,官方实例
public async ValueTask<int> Func()
{
await Task.Delay(100);
return 5;
}
数字文本语法改进
直接上代码演示,看效果
public const int Sixteen = 0b0001_0000;
public const int ThirtyTwo = 0b0010_0000;
public const int OneMillion = 100_0000;
public const int ThreeBillion = 3_0000_0000;
public const double AvogadroConstant = 6.012_140_857_747_474e23;
通过在数字中添加下划线来增加可读性
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/13081.html