如何在C#中默认参数Guid.Empty?

我想说:

public void Problem(Guid optional = Guid.Empty) { } 

但编译器抱怨Guid.Empty不是一个编译时间常量。

由于我不想更改API,我不能使用:

  Nullable<Guid> 

你可以使用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是一个值types而不是引用types,所以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; 

所以,它是一个variables,而不是一个常量(定义为static readonly而不是const )。 编译器只能将编译器已知的值作为方法参数的默认值(而不是运行时已知的)。

根本原因是你不能有任何structconst ,不像enum例如。 如果你尝试,它不会编译。

原因再一次是, struct不是一个原始types。
有关.NET中所有基元types的列表,请参阅http://msdn.microsoft.com/zh-CN/library/system.typecode.aspx
(注意enum通常inheritanceint ,这是一个原语)

new Guid()也不是一个常量!

我并不是说它需要一个常数。 它需要一些可以在编译时决定的东西。 Empty是一个字段,所以它的值在编译时间是不知道的(只在运行时开始)。

在编译时必须知道缺省的参数值,这可能是一个常量值,或者是使用C#特性来定义的,这个特性可以在编译时使值成为已知的,比如default(Guid)或者new Guid()因为你不能修改代码中的struct构造函数)。

虽然您可以轻松地提供defaultnew ,但不能提供const (因为它不是原始types或enum ,如上所述)。 所以,不要说可选参数本身需要一个常量,但是编译器已知的值。

Guid.Empty相当于new Guid() ,相当于default(Guid) 。 所以你可以使用:

 public void Problem(Guid optional = default(Guid)) 

要么

 public void Problem(Guid optional = new Guid()) 

请注意, new Foo()适用于以下情况:

  • 你真的调用了无参数的构造函数
  • Foo是一个值types

换句话说,当编译器知道它实际上只是types的默认值:)

(有趣的是,我99.9%确定它不会调用你可能创build的任何自定义的new Foo()构造函数,你不能在C#中创build这样的构造函数,但是你可以在IL中创build。

您可以使用任何types的default(Foo)选项。

你不能使用:

default ( Guid )

接受的答案在ASP.NET MVC中不起作用,并导致此运行时错误:

 [ArgumentException: The parameters dictionary contains a null entry for parameter 'optional' of non-nullable type 'System.Guid' for method 'System.Web.Mvc.ActionResult Problem(System.Guid)' .... 

相反,您可以执行以下操作:

 public void Problem(Guid? optional) { if (optional == null) { optional = new Guid(); } } 

编译器是非常正确的; Guid.Empty不是编译时常量。 你可以尝试使一个方法超载如下:

 public void Problem() { Problem(Guid.Empty); }