我发现以下代码的 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);
被解析为 SqlParameter(string, SqlDbType)
而对于其他情况则为SqlParameter(字符串,对象)
。但我不明白为什么会这样。对我来说,这看起来像是一个错误,但我不敢相信 C# 编译器会有这样的错误。
有什么原因吗?
附言对于具有枚举参数和 0 值(SqlDbType 是枚举)的任何方法重载,这似乎是一个问题。
最佳答案
基本上,十进制整数文字 0
可隐式转换为所有枚举类型(C# 4 规范 §6.1.3),因此编译器确定 SqlParameter(string, SqlDbType)
是一个适用的函数成员。然后它必须在两个候选函数成员之间选择更好的,它选择 SqlParameter(string, SqlDbType)
而不是 SqlParameter(string, object)
,因为 SqlDbType
是比 object
(§7.5.3.2) 更具体的类型。
但我同意在那种情况下它非常令人困惑......
关于c# - 奇怪的 C# 编译器行为(重载解析),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8228656/