class A
{
public virtual void Foo(int x) { }
}
class B : A
{
public static void Foo(params object[] x) { }
}
class C : B
{
public override void Foo(int x) { }
static void Main()
{
new C().Foo(1);
}
}
Да, это by design.
Здравствуйте, nikov, Вы писали:
N>Да, это by design.
почему компилер предпочтение отдал статик методу??
гуру спецификации поясни плз.. я в спеку залез и вылез оттудова с больной головой.
Здравствуйте, Jericho113, Вы писали:
J>я в спеку залез и вылез оттудова с больной головой.
А какие разделы смотрел?
Здравствуйте, Jericho113, Вы писали:
J>почему компилер предпочтение отдал статик методу??
J>гуру спецификации поясни плз.. я в спеку залез и вылез оттудова с больной головой.
Это работает таким образом (три ключевых момента выделены полужирным шрифтом):
Выражение new C().Foo — это
member-access (описано в 7.5.4 Member access). В процессе определения его значения выполняется member lookup (7.3 Member lookup) в типе C. Сначала строится множество доступных членов с именем Foo (это 3 метода — member lookup никогда
не делает различия между статическими и экземплярными членами), затем
исключаются члены, имеющие модификатор override. Остаются методы A::Foo и B:Foo.
Выражение new C().Foo() — это
invocation-expression (описано в 7.5.5 Invocation expressions, 7.5.5.1 Method invocations). В процессе определения его значения строится множество методов-кандидатов (это методы, применимые к данному списку параметров). В него попадают оба метода A::Foo и B:Foo. Затем множество
урезается, чтобы содержать методы только из самых производных типов. То есть, для каждого метода во множестве, из множества удаляются все методы, определенные в базовых типах по отношению к типу, где определен данный метод. На данном этапе совершенно не важно, какой метод имеет лучшую сигнатуру. Таким образом, во множестве остается только B::Foo. Естественно, он же оказывается лучшим методом (потому что он единственный). Дальше производится окончательная валидация, при которой оказывается, что выбранный метод — статический, но синтаксически вызван как экземплярный, и возникает ошибка компиляции.
Описанный процесс бы несколько усложнился, если бы мы рассматривали вызов методов у выражения, тип которго — тип-параметр, или мы бы рассматривали generic методы или extension методы.