Ian*_*ose 171 c# optional-parameters c#-4.0
我想说:
public void Problem(Guid optional = Guid.Empty)
{
}
Run Code Online (Sandbox Code Playgroud)
但编译器抱怨Guid.Empty不是编译时常量.
由于我不想更改API,我无法使用:
Nullable<Guid>
Run Code Online (Sandbox Code Playgroud)
Mel*_*igy 217
new Guid()改用public void Problem(Guid optional = new Guid())
{
// when called without parameters this will be true
var guidIsEmpty = optional == Guid.Empty;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
它与原始示例完全相同.
Guid.Empty工作?您收到错误的原因是因为Empty定义为:
public static readonly Guid Empty;
Run Code Online (Sandbox Code Playgroud)
所以,它是一个变量,而不是一个常量(定义为static readonly不是const).编译器只能将编译器已知的值作为方法参数的默认值(不仅仅是运行时已知).
根本原因是你不能拥有const任何一个struct,不像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如上所述).所以,再说一遍,并不是说可选参数本身需要一个常量,而是编译器已知值.
Jon*_*eet 149
Guid.Empty相当于new Guid(),相当于default(Guid).所以你可以使用:
public void Problem(Guid optional = default(Guid))
Run Code Online (Sandbox Code Playgroud)
要么
public void Problem(Guid optional = new Guid())
Run Code Online (Sandbox Code Playgroud)
请注意,该new Foo()值仅适用于:
Foo 是一种值类型换句话说,当编译器知道它实际上只是类型的默认值:)
(有趣的是,我99.9%肯定它不会调用new Foo()你可能创建的任何自定义构造函数.你不能在C#中的值类型中创建这样的构造函数,但是你可以在IL中这样做.)
您可以将该default(Foo)选项用于任何类型.
接受的答案在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)' ....
Run Code Online (Sandbox Code Playgroud)
相反,您可以执行以下操作:
public void Problem(Guid? optional)
{
if (optional == null)
{
optional = new Guid();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
68909 次 |
| 最近记录: |