C#的default关键字有两种用法:一种是标记switch…case结构的默认分支(会匹配任意不被所有case条件匹配的路径);另一种方法是表示类型的“默认”值。我将在本文中讨论这个用法。
一个类型的默认值:
- 如果类型是引用类型,则为空
- 如果类型是值类型,则使用这个值类型的无参数构造函数构造出来的实例。
下面的截图是一个简单的例子。
但是,你不能对任何开放类型使用默认表达式(注意:开放类型是具有未绑定类型参数的类型;一个拥有所有的绑定类型参数的类型被称为封闭类型),例如:
现在,如果我们想在一个方法中使用泛型类型的默认值,我们必须写类似这样的代码:
public static void Method(ImmutableArray<int> array) { } public static void Main(string[] args) { Method(default(ImmutableArray<int>)); }
你看到上面代码的冗余了吗?编译器应该知道Method()所需的第一个参数的确切类型。所以一个不需要具体类型的关键字default应该足够了。
默认文本表达式
C# 7.1允许default表达式。如果使用C#语言版本7.1或更新版本进行编译,您可以将代码简化如下:
public static void Method(ImmutableArray<int> array) { } public static void Main(string[] args) { Method(default); }
现在你的代码简洁了!
类似地,你可以在default(…)表达式可以出现的所有地方使用默认文本表达式:
public static void Main(string[] args = default) { // 可选参数的默认值 int i = default; // 类型 System.Int32 的默认值 0 string s = default; // 类型 System.String 的默认值 null Method(default); // 使用参数的默认值调用一个方法 T t = default; // 类型参数的默认值 return default; // 一个有返回值的方法返回默认值 }
你还能够在判断条件中使用默认文本表达式
int x = 2; if (x == default) { } // 判断x是否是类型 System.Int32 的默认值 0 if (x is default) { } // 同上
更有趣的是,您可以在switch…case语句中使用默认文本表达式。哦,太酷了!等一下,要是我输入"case default"标签呢?下面这张图是我在VS中输入case default的截图:
如果你使用VS的建议来修改你的语句,就会变成下面这样:
int x = 2; switch (x) { case (default): break; //译注:VS建议使用case 0 或者 case null来代替。 default: break; }
这看起来很让人困惑,但至少我们得到了关于这个的实时分析,感谢Roslyn!(译注:C#编译器)
我想说的最后一件事是,有些情况下不能应用默认文本表达式,例如:
// 错误: ‘as‘ 必须用在引用类型 default as int; // OK. 但是左边的表达式总是null。 if (default as string == string.Empty) { } // 错误,不能对default关键字使用操作符is。 if (default is string) { }
结论
C# 7.1中的默认文本表达式避免了编译器知道默认值时的冗余输入。这是语法上的改进,CLR没有任何变化,新代码与C#编译器早期版本构建的代码100%兼容。
系列文章:
[译]C# 7系列,Part 3: Default Literals
原文:https://www.cnblogs.com/wenhx/p/csharp-7-series-part-3-default-literals.html