C# 8.0 以后
官网
C# 7.3
》》in
C# 7.2
》》 命名参数、具名参数
》》》 条件 ref 表达式
C# 7.1
》》 default 运算符
default 在C#7.1中得到了改进,不再需要default(T)了
//变量赋值
C#7.0
var s = "字符串";
s = default(string);
C#7.1
var s = "字符串";
s = default;
//初始化赋值
C#7.0
var dstring = default(string);
var dint = default(int);
var dintNull = default(int?);
var d = default(dynamic);
var dt = default(DateTime);
var dt1 = default(DateTime?);
C#7.1
string s = default;
int i = default;
DateTime? dt = default;
dynamic d = default;
//可选参数
C#7.0
void Test(int a, string b = default(string))
{
}
C#7.1
void Test(int a, string b = default)
{
}
》》》 元组功能提供了简洁的语法来将多个数据元素分组成一个轻型数据结构。
(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}.");
// 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。
static IEnumerable<int> Factor(int number)
{
int max = (int)Math.Sqrt(number);
for (int i = 1; i <= max; i++)
{
if (number % i == 0)
{
yield return i;
if (i != number / i)
{
yield return number / i;
}
}
}
}
int[] testSet = { 22, 33, 44, 55};
var primes = testSet.Where(n => Factor(n).ToList() is var factors
&& factors.Count == 2
&& factors.Contains(1)
&& factors.Contains(n));
》》》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(
"first:tuple.one,second:tuple.two");。方式2:定义:vartuple2=(one:1,two:2);使用:WriteLine(“first:{tuple2.one}, second:{tuple2.two}”);。
》》》本地方法
》》 Ref
对ref引用进行了加强,现在可以引用一个方法中的局部变量,
语法是:在方法定义前加上 ref,同时在返回时也加上ref,
如定义函数
ref int GetDataRef(int[] data, int index)
{
return ref data[index];
}
ref int num = ref GetDataRef(new data[]{1,2,3}, 0);
则 ref int num = ref 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)。
》》只读自动属性
只读自动属性提供了更简洁的语法来创建不可变类型。 你声明仅具有 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 成员在声明它的位置处被初始化。 这样,就能更容易地仅执行一次初始化。 初始化是属性声明的一部分,可更轻松地将存储分配。
》》 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时则返回b,a不为null时则返回a本身。
》》字符串内插
使用 C# 6,新的字符串内插功能可以在字符串中嵌入表达式。
使用 $ 作为字符串的开头,并使用 { 和 } 之间的表达式代替序号:
public string FullName => $“{FirstName} {LastName}”;
》》异常筛选器
try{
doSomething();
} catch(Exception e) when (e.Message.Contains("xx")){
ProcessException(e);
}
//等价于
catch (Exception e)
{
if(e.Message.Contains("xx")) // 如果判断的逻辑较多,建议使用该方式。
{
return "Site Moved";
}
}
》》 nameof
Nameof是一个运算符,用于获取代码元素(如变量、类和方法等)的名称(是的,字符串)。
它通过将名称作为字符串文字返回来帮助您密切关注名称!
int myInt = 10;
Console.WriteLine(nameof(myInt)); // Output: “myInt”
》》索引器初始化关联集合, C# 3.0 集合初始化器