解决方案
您可以改用new Guid()
public void Problem(Guid optional = new Guid())
{
// when called without parameters this will be true
var guidIsEmpty = optional == Guid.Empty;
}
你也可以使用default(Guid)
default(Guid) 也将与new Guid() 完全相同。
由于 Guid 是值类型而不是引用类型,所以,default(Guid) 不等于 null,而是等于调用默认构造函数。
这意味着:
public void Problem(Guid optional = default(Guid))
{
// when called without parameters this will be true
var guidIsEmpty = optional == Guid.Empty;
}
和原来的例子一模一样。
说明
为什么Guid.Empty 不起作用?
您收到错误的原因是因为Empty 定义为:
public static readonly Guid Empty;
所以,它是一个变量,而不是一个常量(定义为 static readonly 而不是 const)。编译器只能将编译器已知的值作为方法参数的默认值(不是运行时已知的)。
根本原因是您不能拥有任何struct 的const,这与enum 不同。如果你尝试它,它不会编译。
原因再次是struct 不是原始类型。
有关 .NET 中所有原始类型的列表,请参阅http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(注意enum通常继承int,这是一个原语)
但new Guid() 也不是常数!
我并不是说它需要一个常数。它需要一些可以在编译时决定的东西。 Empty 是一个字段,因此,它的值在编译时是未知的(仅在运行时的最开始时)。
必须在编译时知道默认参数值,它可以是 const 值,或者使用 C# 特性定义的值,在编译时知道值,例如 default(Guid) 或 new Guid()(由在 structs 的编译时,因为您无法在代码中修改 struct 构造函数。
虽然您可以轻松提供default 或new,但您不能提供const(因为它不是原始类型或enum,如上所述)。所以,再说一遍,并不是说可选参数本身需要一个常量,而是编译器已知的值。