c#2.0中可为空值的默认值

20 .net c# c#-2.0

使用C#2.0,我可以指定一个默认参数值,如下所示:

static void Test([DefaultParameterValueAttribute(null)] String x) {}
Run Code Online (Sandbox Code Playgroud)

由于此C#4.0语法不可用:

static void Test(String x = null) {}
Run Code Online (Sandbox Code Playgroud)

那么,值类型的C#2.0是否相同?例如:

static void Test(int? x = null) {}
Run Code Online (Sandbox Code Playgroud)

以下尝试无法编译.

// error CS1908: The type of the argument to the DefaultValue attribute must match the parameter type
static void Test([DefaultParameterValueAttribute(null)] int? x) {}

// error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression
static void Test([DefaultParameterValueAttribute(new Nullable<int>())] int? x) {}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 14

不幸的是,旧版本的C#编译器不支持这一点.

C#4.0编译器编译如下:

public static void Foo(int? value = null)
Run Code Online (Sandbox Code Playgroud)

成:

public static void Foo([Optional, DefaultParameterValue(null)] int? value)
Run Code Online (Sandbox Code Playgroud)

这实际上与第一次尝试(OptionalAttribute另外添加)相同,C#2编译器在CS1908上出错,因为在该版本的编译器中不直接支持.

如果您需要支持C#2,在这种情况下,我建议您添加重载方法:

static void Test()
{
    Test(null);
}
static void Test(int? x)
{
    // ..
Run Code Online (Sandbox Code Playgroud)


Eri*_*ert 10

里德当然是正确的; 我只是想我会在一个角落案例中添加一个有趣的事实.在C#4.0中,您可以说:(对于结构类型S)

void M1(S x = default(S)) {}
void M2(S? x = null) {}
void M3(S? x = default(S?)) {}
Run Code Online (Sandbox Code Playgroud)

但奇怪的是你不能说

void M4(S? x = default(S)) {}
Run Code Online (Sandbox Code Playgroud)

在前三种情况下,我们可以简单地发出元数据,其中"可选值是形式参数类型的默认值".但在第四种情况下,可选值是不同类型的默认值.没有一种明显的方法可以将这种事实编码到元数据中.我们只是在C#中将其设置为非法,而不是针对如何编码这样的事实提出跨语言的一致规则.这可能是一个罕见的角落案件,所以没有很大的损失.