使用 default 作为可为 null 的值类型参数的默认值不会分配 null
Using default as a default value for a nullable value type parameter does not assign null
微软的 post default value expressions (C# programming guide) 解释了 default(T)
的用法和行为。行为(现在仍然)如下:
var x = default(uint?);
Assert.IsNull(x); // ok
uint? y = default;
Assert.IsNull(y); // ok
然后 post 继续解释了 C# 7.1 中引入的 default
(default literal and type inference) 的用法和行为。在 C# 7.1 之前我们做了:
void BeforeCsharp7_1(uint? z = default(uint?))
{
Assert.IsNull(z); // ok
}
使用 C# 7.1 我们可以做到:
void WithCsharp7_1(uint? z = default)
{
Assert.IsNull(z); // Fail, expected null but was 0
}
您可能会惊讶地发现最后一个片段不会断言,因为参数 z
等于 0
。将我的项目升级到 C# 7.1 后,Visual Studio 一直告诉我 default(uint?)
可以简化为 default
,这会导致这种非常不同的行为。这一定是 Visual Studio 中的错误。
这也是 C# 规范/Roslyn 中的错误还是设计使然?
这是一个 bug in Roslyn,现已在 VS15.5 / .NET Core SDK 2.1.200 及更高版本中修复。是的,对于可空值类型,默认文字确实应该 return null
。
微软的 post default value expressions (C# programming guide) 解释了 default(T)
的用法和行为。行为(现在仍然)如下:
var x = default(uint?);
Assert.IsNull(x); // ok
uint? y = default;
Assert.IsNull(y); // ok
然后 post 继续解释了 C# 7.1 中引入的 default
(default literal and type inference) 的用法和行为。在 C# 7.1 之前我们做了:
void BeforeCsharp7_1(uint? z = default(uint?))
{
Assert.IsNull(z); // ok
}
使用 C# 7.1 我们可以做到:
void WithCsharp7_1(uint? z = default)
{
Assert.IsNull(z); // Fail, expected null but was 0
}
您可能会惊讶地发现最后一个片段不会断言,因为参数 z
等于 0
。将我的项目升级到 C# 7.1 后,Visual Studio 一直告诉我 default(uint?)
可以简化为 default
,这会导致这种非常不同的行为。这一定是 Visual Studio 中的错误。
这也是 C# 规范/Roslyn 中的错误还是设计使然?
这是一个 bug in Roslyn,现已在 VS15.5 / .NET Core SDK 2.1.200 及更高版本中修复。是的,对于可空值类型,默认文字确实应该 return null
。