C#方法解析,long vs int

Veg*_*gar 39 c# methods resolution

class foo
{
  public void bar(int i) { ... };
  public void bar(long i) { ... };
}


foo.bar(10);
Run Code Online (Sandbox Code Playgroud)

我希望这段代码能给我一些错误,或者至少是一个警告,但不是这样......

调用什么版本的bar(),为什么?

kem*_*002 54

正在调用bar的int版本,因为它10是一个int文字,编译器将查找与输入变量最匹配的方法.要调用长版本,您需要指定一个长文字,如下所示:foo.bar(10L);

以下是Eric Lippert关于更复杂的方法重载版本的文章.我试着解释一下,但他做得更好,我曾经做过:http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part- one.aspx

来自C#4.0规范:

方法重载允许同一类中的多个方法具有相同的名称,只要它们具有唯一的签名即可.在编译重载方法的调用时,编译器使用重载决策来确定要调用的特定方法.如果找不到单个最佳匹配,则重载决策会找到最匹配参数的一种方法或报告错误.以下示例显示了有效的重载决策.Main方法中每次调用的注释显示实际调用的方法.

 class Test {   
      static void F() {
        Console.WriteLine("F()");   
      }     
      static void F(object x) {
        Console.WriteLine("F(object)");     
      }
      static void F(int x) {
        Console.WriteLine("F(int)");    
      }
      static void F(double x) {
        Console.WriteLine("F(double)");     
      }
      static void F<T>(T x) {
        Console.WriteLine("F<T>(T)");   
      }
      static void F(double x, double y) {
        Console.WriteLine("F(double,double)");  
      }     

      static void Main() {
        F();                // Invokes F()
        F(1);           // Invokes F(int)
        F(1.0);         // Invokes F(double)
        F("abc");       // Invokes F(object)
        F((double)1);       // Invokes F(double)
        F((object)1);       // Invokes F(object)
        F<int>(1);      // Invokes F<T>(T)
        F(1, 1);        // Invokes F(double, double)
      } 
}
Run Code Online (Sandbox Code Playgroud)

如示例所示,始终可以通过将参数显式地转换为确切的参数类型和/或显式提供类型参数来选择特定方法.


Eri*_*ert 12

正如凯文所说,有一个重载解决过程.该过程的基本草图是:

  • 确定所有可访问的候选方法,可能使用泛型方法的类型推断
  • 过滤掉不适用的方法; 也就是说,由于参数不会隐式转换为参数类型,因此无法工作的方法.
  • 一旦我们有了一组适用的候选人,就可以对他们运行更多过滤器以确定唯一最佳的候选人.

过滤器非常复杂.例如,最初在更多派生类型中声明的方法总是比最少在派生类型中声明的方法更好.参数类型与参数类型完全匹配的方法优于不精确匹配的方法.等等.有关确切规则,请参阅规范.

在您的特定示例中,"更好"算法很简单.int与int的完全匹配优于int与long的不精确匹配.