【问题标题】:Null-Coallescing Operator - Why Casting?Null-Coalescing Operator - 为什么要强制转换?
【发布时间】:2011-09-14 01:30:09
【问题描述】:

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

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

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

【问题讨论】:

  • 编译错误究竟是什么? NewDatabase.AddInParameter的签名是什么?
  • 签名是void AddInParameter(DbCommand, string, DBType, object)。编译错误是“运算符'??'不能应用于“字符串”和“System.DBNull”类型的操作数”。

标签: c# .net casting nullable null-coalescing-operator


【解决方案1】:

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

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

表达式a ?? b 的类型取决于操作数上可用的隐式转换。按照优先顺序,a ?? b 的类型是A0AB,其中Aa 的类型(前提是a 有类型),Bb 的类型(假设 b 具有类型),如果 A 是可空类型,A0A 的基础类型,否则 A

【讨论】:

    【解决方案2】:

    第一个示例失败,因为 SomeStringDBValue.Null 不是 implicitly interchangable types

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 转换也可以反过来——从左到右。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-01
          • 2011-05-10
          • 1970-01-01
          • 1970-01-01
          • 2014-03-16
          • 2012-03-17
          • 1970-01-01
          • 2021-05-08
          相关资源
          最近更新 更多