概述
在以下上下文中,可以使用 default 关键字:
- 指定 switch 语句中的默认事例。
- 作为 default 默认运算符或文本生成类型的默认值。
- 作为泛型方法重写或显式接口实现上的 default 类型约束。
指定 switch 语句中的默认事例
DisplayMeasurement(-4); // Output: Measured value is -4; too low.
DisplayMeasurement(5); // Output: Measured value is 5.
DisplayMeasurement(30); // Output: Measured value is 30; too high.
DisplayMeasurement(double.NaN); // Output: Failed measurement.
void DisplayMeasurement(double measurement)
{
switch (measurement)
{
case < 0.0:
Console.WriteLine($"Measured value is {
measurement}; too low.");
break;
case > 15.0:
Console.WriteLine($"Measured value is {
measurement}; too high.");
break;
case double.NaN:
Console.WriteLine("Failed measurement.");
break;
default:
Console.WriteLine($"Measured value is {
measurement}.");
break;
}
}
作用是:不满足所有case的情况下,会进default, 若不写则直接跳出switch
作为 default 默认运算符或文本生成类型的默认值
类型 | 默认值 |
---|---|
任何引用类型 | null |
数值类型 | 零 |
bool | false |
enum | 表达式 (E)0 生成的值,其中 E 是枚举标识符。 |
struct | 通过如下设置生成的值:将所有值类型的字段设置为其默认值,将所有引用类型的字段设置为null。 |
可以为 null 的类型 | HasValue 属性为 false 且 Value 属性未定义的实例。 |
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)
{
}
作为泛型方法重写或显式接口实现上的 default 类型约束
添加可为空引用类型可能会在泛型方法的 T? 含义中产生歧义。 如果 T 是 struct,则 T? 与 System.Nullable 相同。 但是,如果 T 是引用类型,则 T? 表示 null 是有效值。 出现歧义的原因是,重写方法不能包含约束。 新 default 约束解决了这种歧义。 当基类或接口声明一个方法的两个重载(一个指定 struct 约束,另一个未应用 struct 或 class 约束)时,将添加该约束:
public abstract class B
{
public void M<T>(T? item) where T : struct {
}
public abstract void M<T>(T? item);
}
使用 default 约束来指定派生类在派生类中没有约束的情况下重写方法,或指定显式接口实现。 此做法仅对重写基方法的方法或显式接口实现有效:
public class D : B
{
// Without the "default" constraint, the compiler tries to override the first method in B
public override void M<T>(T? item) where T : default {
}
}