C#中的null合并运算符是什么?

9
我已经将类 Person 的属性 Birthday 定义为 nullable DateTime?,那么为什么在以下示例中,空值合并运算符不起作用呢?
cmd.Parameters.Add(new SqlParameter("@Birthday",
   SqlDbType.SmallDateTime)).Value =       
     person.Birthday ?? DBNull.Value; 

我得到的编译器错误是“运算符'??'不能应用于类型为'System.DateTime?'和'System.DBNull'的操作数”。
以下内容也出现了编译错误:
cmd.Parameters.Add(new SqlParameter("@Birthday", 
  SqlDbType.SmallDateTime)).Value = 
   (person.Birthday == null) ? person.Birthday:DBNull.Value;

根据Refactor的建议,我添加了一个(object)的转换,虽然编译通过了,但实际上并没有正常工作,无论在哪种情况下,该值都被存储为null在sqlserver数据库中。

SqlDbType.SmallDateTime)).Value =       
         person.Birthday ?? (object)DBNull.Value;

有人能解释一下这是怎么回事吗?

我需要使用以下笨拙的代码:

   if (person.Birthday == null) 
    cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value 
      = DBNull.Value;
     else cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value = 
          person.Birthday;

3
这是一个重复的问题:C# ADO.NET中的null和DBNull,是否存在更有效的语法? - sgriffinusa
从另一篇帖子中得到了这个:SqlDbType.SmallDateTime)).Value = person.Birthday ?? (object)DBNull.Value; 谢谢! - Lill Lansey
3个回答

23
问题在于`DateTime?`和`DBNull.Value`不是相同类型,所以你不能在它们上面使用null合并运算符。
在您的情况下,您可以执行`person.Birthday ?? (object)DBNull.Value`,将一个类型为`object`的值传递给`Add()`函数。

5

在执行查询之前,我更喜欢迭代我的参数,根据需要将所有的null实例更改为DBNull,例如:

foreach (IDataParameter param in cmd.Parameters)
    if (param.Value == null)
        param.Value = DBNull.Value;

这让我可以保留空值并稍后集中替换它们,而无需进行解释。

我对此的问题在于事后迭代参数会增加额外的开销,而立即处理它们则不同。 - Andrew

3

你面临的第一个问题是,在使用 ???: 运算符时,两个选择的对象必须是相同类型的。而在这里,它们是不同类型的。


1
那么 ?: 是什么作用?编辑:算了,我知道了,只是以前从未见过这两个符号放在一起。http://msdn.microsoft.com/en-us/library/ty67wk28.aspx - Allen Rice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接