4

谁能告诉我为什么以下语句中的第一个会引发编译错误而第二个不会?

NewDatabase.AddInParameter(NewCommand, "@SomeString", DbType.String, SomeString ?? DBNull.Value); // <-- Throws compilation error!
NewDatabase.AddInParameter(NewCommand, "@SomeString", DbType.String, (object)(SomeString) ?? DBNull.Value); // <-- Compiles!

我尝试了其他可以为空的类型,例如byte?并得到了相同的结果。谁能告诉我为什么我需要先投反对票?

4

5 回答 5

10

你需要告诉编译器使用什么类型。空合并运算符的结果类型必须与其中一个操作数类型(或第一个操作数的基础类型,如果它是可空值类型,在某些情况下)相同。它不会尝试找到“两个操作数都可以转换为的最具体的类型”或类似的东西。

有关 null 合并运算符如何定义语言的详细信息,请参阅C# 4 语言规范,第 7.13 节:

表达式的类型a ?? b取决于操作数上可用的隐式转换。按优先顺序, 的类型a ?? bA0AB,其中A是 的类型a(假设 a 有类型),B是的类型b(前提是b有类型),并且A0Aif的基础类型A是可空类型,或A其他。

于 2011-06-13T16:23:25.557 回答
9

第一个示例失败,因为SomeString并且DBValue.Null不是隐式可互换类型

于 2011-06-13T16:22:41.090 回答
4

这是因为 null 合并运算符右侧的类型必须隐式转换为左侧的类型(反之亦然)。对于您的第一个示例,所涉及的类型是stringDBNull。这些类型不相关,因此转换失败。

于 2011-06-13T16:24:08.447 回答
2

DBValue.Null 不是字符串;它是一个对象。.NET 不会在表达式中隐式转换为 Object;必须明确告知您期待一个 Object 结果。

于 2011-06-13T16:25:02.307 回答
2

因为表达式需要有一个单一的返回类型。由于String并且DbValue不能相互转换,编译器无法确定您想要哪种类型的返回。当您转换为 Object 时,您正在为编译器提供它可以转换为的类型。

于 2011-06-13T16:26:39.047 回答