11

我发现以下代码的 C# 编译器行为非常奇怪:

    var p1 = new SqlParameter("@p", Convert.ToInt32(1));
    var p2 = new SqlParameter("@p", 1);
    Assert.AreEqual(p1.Value, p2.Value); // PASS

    var x = 0;
    p1 = new SqlParameter("@p", Convert.ToInt32(x));
    p2 = new SqlParameter("@p", x);
    Assert.AreEqual(p1.Value, p2.Value); // PASS

    p1 = new SqlParameter("@p", Convert.ToInt32(0));
    p2 = new SqlParameter("@p", 0);
    Assert.AreEqual(p1.Value, p2.Value); // FAIL!?

在最后一行断言失败并显示以下消息:

  Expected: 0
  But was:  null

我理解测试失败的原因:在其他情况下p2 = new SqlParameter("@p", 0);解决为. 但我不明白为什么会这样。对我来说它看起来像一个错误,但我无法相信 C# 编译器会有这样的错误。SqlParameter(string, SqlDbType)SqlParameter(string, object)

这有什么原因吗?

PS对于任何带有枚举参数和0值的方法重载似乎都是一个问题(SqlDbType是枚举)。

4

1 回答 1

11

基本上,十进制整数文字0可隐式转换为所有枚举类型(C# 4 规范 §6.1.3),因此编译器确定它SqlParameter(string, SqlDbType)是适用的函数成员。然后它必须在两个候选函数成员之间选择更好的,然后选择SqlParameter(string, SqlDbType)SqlParameter(string, object)因为SqlDbType它是比object(第 7.5.3.2 节)更具体的类型。

但我同意在那种情况下它会非常混乱......

于 2011-11-22T14:51:52.537 回答