c# 2.0 中可空值的默认值

Posted

技术标签:

【中文标题】c# 2.0 中可空值的默认值【英文标题】:Default value for nullable value in c# 2.0 【发布时间】:2011-11-21 17:01:53 【问题描述】:

使用 C# 2.0,我可以像这样指定默认参数值:

static void Test([DefaultParameterValueAttribute(null)] String x) 

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

static void Test(String x = null) 

那么,值类型是否有 C# 2.0 等效项?例如:

static void Test(int? x = null) 

以下尝试无法编译。

// 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) 

【问题讨论】:

这是为了开发一个供外部语言调用的库吗? 是的,它是一个图书馆。该代码实际上是使用 CSharpCodeProvider 生成的,并且只是调用到专有 C++ 变体类的 C++/CLI 接口。 “企业”。 【参考方案1】:

很遗憾,旧版本的 C# 编译器不支持此功能。

C# 4.0 编译器编译这个:

public static void Foo(int? value = null)

进入:

public static void Foo([Optional, DefaultParameterValue(null)] int? value)

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

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

static void Test()

    Test(null);

static void Test(int? x)

    // ..

【讨论】:

【参考方案2】:

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

void M1(S x = default(S)) 
void M2(S? x = null) 
void M3(S? x = default(S?)) 

但奇怪的是你不能说

void M4(S? x = default(S)) 

在前三种情况下,我们可以简单地发出表示“可​​选值是形式参数类型的默认值”的元数据。但在第四种情况下,可选值是不同类型的默认值。没有一种明显的方法可以将这种事实编码到元数据中。我们没有为如何编码这样的事实制定跨语言的一致规则,而是在 C# 中简单地将其设为非法。这可能是一个罕见的极端情况,所以不会有太大的损失。

【讨论】:

【参考方案3】:

显然你不能使用这个属性。

如您所知,属性参数在编译时被“序列化”为元数据——因此您需要常量表达式。由于编译器不喜欢'null',所以你没有选择。

你可以做的是 - 重载 - 定义另一个没有参数的 Text 方法,它使用 null 调用你的 Text 方法

【讨论】:

【参考方案4】:

这是否有效:[DefaultParameterValueAttribute((int?)null)]? 试过 - 这也不起作用(

【讨论】:

是的,您确实可以强制转换空引用。由于其他原因,它不起作用。 实际上在 Nullable 的情况下 - 我们可以使用强制转换,因为它是一个特殊的结构(不是类)。例如,此 e 表达式有效:int? a = isSomethingTrue ? (int?)null : 1;。回到原来的问题......似乎 DefaultParameterValueAttribute '认为' struct 不能有空值 - 看起来像一个错误。 此外,我们仍然有能力以某种疯狂的方式解决问题:1) 使用带有 object 参数的构造函数定义自定义属性 CustomDefaultParameterValueAttribute : Attribute,2) 将此新属性应用于目标参数. 3) 创建一个将使用 Mono.Cecil 打开编译库并将 CustomDefaultParameterValueAttribute 替换为 DefaultParameterValueAttribute 的新项目。但正如您所了解的,定义另一个无参数方法要容易得多:)【参考方案5】:

我认为应该是:

static void Text(int? x = default(int?));

【讨论】:

那是针对 C# 4.0 的。他在问在 C# 2.0 中使用属性时的等价物是什么。 啊。我误解了这个问题。我以为他是在说它在 4.0 中不起作用。对不起。

以上是关于c# 2.0 中可空值的默认值的主要内容,如果未能解决你的问题,请参考以下文章

嵌套js代码中可空值的可空数组首先graphql

C#进阶系列18 可空值类型

将可空整数初始化为默认值的最佳实践?

c# 中的可空类型是啥?

WCF中可为空值类型的错误

如何通过 C# 将可空整数列的空值插入 SQL 表