重载分辨率奇怪

lep*_*pie 6 .net c# overload-resolution

不确定这是否特定于C#4+,但只是注意到了这一点.

考虑以下类:

class Base
{
  protected void Foo(object bar, DayOfWeek day)
  {
  }
}

class Program : Base
{
  protected void Foo(object bar, object baz)
  {
  }

  void Bar(DayOfWeek day)
  {
    Foo(new { day }, day);
  }
}
Run Code Online (Sandbox Code Playgroud)

在调用Foo中Bar,做出决议Foo(object, object).

将其更改为:

class Base
{

}

class Program : Base
{
  protected void Foo(object bar, object baz)
  {
  }

  protected void Foo(object bar, DayOfWeek day)
  {
  }

  void Bar(DayOfWeek day)
  {
    Foo(new { day }, day);
  }
}
Run Code Online (Sandbox Code Playgroud)

在调用Foo中Bar,做出决议Foo(object, DayOfWeek).

我的理解是它应该像第二个例子一样解决.

这是一个'错误'还是我缺乏理解(或无知)?

更新:

谢谢你的回答.正如我所知,可以使用base.在基类中调用该方法.然而,当在混合中添加另一个派生类时,问题又回来了.

class Base
{
  protected void Foo(object bar, DayOfWeek day)
  {
  }
}

class Program : Base
{
  protected void Foo(object bar, object baz)
  {
  }

  void Bar(DayOfWeek day)
  {
    base.Foo(new { day }, day);
  }
}

class Derived : Program
{
  void Baz(DayOfWeek day)
  {
    base.Foo(new { day }, day);
  }
}
Run Code Online (Sandbox Code Playgroud)

该base.呼叫在工作Program,但然后会Foo(object, object)在Derived.

一个人怎么会叫Foo(object,DayOfWeek)的Derived那么无需创建在"冗余"的方法Program?

Hab*_*bib 6

我认为对于解析方法调用它首先在它的类中查找,因为DayOfWeek可以作为object类型传递,它调用类自己的方法,而不是基类中的方法.

在第二种情况下,方法调用解析为更具体的类型参数,因此Foo(object bar, DayOfWeek day)被调用.

从MSDN - 方法解析.

在一个方法中基类不是候选如果在派生类的任何方法都是适用的(见第7.5.5.1).

  • 给定一组适用的候选函数成员,找到该集合中的最佳函数成员.
  • 如果集合只包含一个函数成员,那么该函数成员是最好的函数成员.
  • 否则,最好的函数成员是一个函数成员,它比给定参数列表中的所有其他函数成员更好,只要使用第7.4.2.2节中的规则将每个函数成员与所有其他函数成员进行比较.
  • 如果没有一个函数成员优于所有其他函数成员,则函数成员调用不明确并且发生编译时错误.