c# - 奇怪的 C# 编译器行为(重载解析)

标签 c# .net overload-resolution

我发现以下代码的 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/

相关文章:

c# - 有延迟的链接任务

c# - 从我的服务器下载 zip 文件时遇到问题

.net - 使用 NLog 记录异常时如何获取堆栈跟踪?

c++ - 当两个模板参数类型相同时如何进行偏特化?

c# - 处理多个配置文件实例的最佳方式?

c# - 2 TcpClient 在同一台机器和端口上

C#将一条记录从一个字典复制到另一个

c# - CIL是汇编语言,JIT是汇编程序吗

C++运算符==和隐式转换解析

c# - 如果不涉及歧义,为什么添加方法会添加歧义调用