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

发布于 2024-10-19 03:19:55 字数 202 浏览 2 评论 0原文

我想说:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无尽的现实 2024-10-26 03:19:55

解决方案

您可以使用 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) 也将与 完全相同新的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< /代码>)。编译器只能将编译器已知的值作为方法参数默认值(而不是仅运行时已知的值)。

根本原因是您不能拥有任何 structconst,这与 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 构造函数)。

虽然您可以轻松提供 defaultnew ,但您无法提供 const (因为它不是原始类型或 enum代码>如上所述)。所以,再说一遍,并不是说可选参数本身需要一个常量,而是编译器已知的值。

Solution

You can use new Guid() instead

public void Problem(Guid optional = new Guid())
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

You can also use default(Guid)

default(Guid) also will work exactly as new Guid().

Because Guid is a value type not reference type, so, default(Guid) is not equal to null for example, instead, it's equal to calling default constructor.

Which means that this:

public void Problem(Guid optional = default(Guid))
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

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:

public static readonly Guid Empty;

So, it is a variable, not a constant (defined as static readonly not as const). 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 any struct, unlike enum 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 inherits int, 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, like default(Guid) or new Guid() (which is decided at compile time for structs as you cannot modify the struct constructor in code).

While you can provide default or new easily, you cannot provide a const (because it's not a primitive type or an enum as explained above). So, again, not saying that optional parameter itself needs a constant, but compiler known value.

涫野音 2024-10-26 03:19:55

Guid.Empty 相当于 new Guid(),它相当于 default(Guid)。因此您可以使用:

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

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

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

  • 您确实在调用无参数构造函数
  • Foo 是一个值类型

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

(有趣的是,我 99.9% 确定它不会调用您可能创建的任何自定义 new Foo() 构造函数您无法在 C# 中的值类型中创建此类构造函数,但您可以在 IL 中这样做。)

您可以对任何类型使用default(Foo)选项。

Guid.Empty is equivalent to new Guid(), which is equivalent to default(Guid). So you can use:

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

or

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

Note that the new Foo() value is only applicable when:

  • You're really calling the parameterless constructor
  • Foo is a value type

In 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.

伴梦长久 2024-10-26 03:19:55

你不能使用:

default (Guid)吗?

Can't you use:

default ( Guid ) ?

终难愈 2024-10-26 03:19:55

接受的答案在 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();
    }
}

The accepted answer does not work in ASP.NET MVC, and cause this run-time error:

[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)' ....

Instead, you may do the following:

public void Problem(Guid? optional)
{
    if (optional == null)
    {
        optional = new Guid();
    }
}
孤君无依 2024-10-26 03:19:55

编译器是完全正确的; Guid.Empty 不是编译时常量。您可以尝试像这样进行方法重载:

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

The compiler is quite correct; Guid.Empty is not a compile-time constant. You can try making a method overload like this:

public void Problem()
{
    Problem(Guid.Empty);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文