如何在 C# 中将参数默认为 Guid.Empty?
我想说:
public void Problem(Guid optional = Guid.Empty)
{
}
但是编译器抱怨 Guid.Empty 不是编译时常量。
因为我不想更改 API,所以我无法使用:
Nullable<Guid>
I wish to say:
public void Problem(Guid optional = Guid.Empty)
{
}
But the compiler complains that Guid.Empty is not a compile time constant.
As I don’t wish to change the API I can’t use:
Nullable<Guid>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
解决方案
您可以使用
new Guid()
代替您也可以使用
default(Guid)
default(Guid)
也将与完全相同新的Guid()。
因为 Guid 是值类型而不是引用类型,所以
default(Guid)
不等于null
例如,它相当于调用默认构造函数。这意味着:
它与原始示例完全相同。
解释
为什么
Guid.Empty
不起作用?您收到错误的原因是因为
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)default(Guid) code> 或 new Guid() (这是在
struct
的编译时决定的,因为您无法修改代码中的struct
构造函数)。虽然您可以轻松提供
default
或new
,但您无法提供const
(因为它不是原始类型或enum
代码>如上所述)。所以,再说一遍,并不是说可选参数本身需要一个常量,而是编译器已知的值。Solution
You can use
new Guid()
insteadYou can also use
default(Guid)
default(Guid)
also will work exactly asnew Guid()
.Because Guid is a value type not reference type, so,
default(Guid)
is not equal tonull
for example, instead, it's equal to calling default constructor.Which means that this:
It's exactly the same as the original example.
Explanation
Why didn't
Guid.Empty
work?The reason you are getting the error is because
Empty
is defined as:So, it is a variable, not a constant (defined as
static readonly
not asconst
). Compiler can only have compiler-known values as method parameters default values (not runtime-only-known).The root cause is that you cannot have a
const
of anystruct
, unlikeenum
for example. If you try it, it will not compile.The reason once more is that
struct
is not a primitive type.For a list of all primitive types in .NET see http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(note that
enum
usually inheritsint
, which is a primitive)But
new Guid()
is not a constant too!I'm not saying it needs a constant. It needs something that can be decided in compile time.
Empty
is a field, so, it's value is not known in compile time (only at very beginning of run time).Default parameter value must be known at compile-time, which may be a
const
value, or something defined using a C# feature that makes value known at compile time, likedefault(Guid)
ornew Guid()
(which is decided at compile time forstruct
s as you cannot modify thestruct
constructor in code).While you can provide
default
ornew
easily, you cannot provide aconst
(because it's not a primitive type or anenum
as explained above). So, again, not saying that optional parameter itself needs a constant, but compiler known value.Guid.Empty
相当于new Guid()
,它相当于default(Guid)
。因此您可以使用:或
请注意,
new Foo()
值仅适用于以下情况:Foo
是一个值类型换句话说,当编译器知道它实际上只是该类型的默认值时:)
(有趣的是,我 99.9% 确定它不会调用您可能创建的任何自定义
new Foo()
构造函数您无法在 C# 中的值类型中创建此类构造函数,但您可以在 IL 中这样做。)您可以对任何类型使用
default(Foo)
选项。Guid.Empty
is equivalent tonew Guid()
, which is equivalent todefault(Guid)
. So you can use:or
Note that the
new Foo()
value is only applicable when:Foo
is a value typeIn other words, when the compiler knows it's really just the default value for the type :)
(Interestingly, I'm 99.9% sure it won't call any custom
new Foo()
constructor you may have created. You can't create such a constructor in a value type in C#, but you can do so in IL.)You can use the
default(Foo)
option for any type.你不能使用:
default (Guid)
吗?Can't you use:
default ( Guid )
?接受的答案在 ASP.NET MVC 中不起作用,并导致此运行时错误:
相反,您可以执行以下操作:
The accepted answer does not work in ASP.NET MVC, and cause this run-time error:
Instead, you may do the following:
编译器是完全正确的;
Guid.Empty
不是编译时常量。您可以尝试像这样进行方法重载:The compiler is quite correct;
Guid.Empty
is not a compile-time constant. You can try making a method overload like this: