Еще один интересный эффект
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.07.08 10:38
Оценка:
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.
Re: Еще один интересный эффект
От: Jericho113 Украина  
Дата: 02.07.08 11:38
Оценка:
Здравствуйте, nikov, Вы писали:


N>Да, это by design.


почему компилер предпочтение отдал статик методу??
гуру спецификации поясни плз.. я в спеку залез и вылез оттудова с больной головой.
NetDigitally yours ....
Re[2]: Еще один интересный эффект
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.07.08 11:48
Оценка:
Здравствуйте, Jericho113, Вы писали:

J>я в спеку залез и вылез оттудова с больной головой.


А какие разделы смотрел?
Re[2]: Еще один интересный эффект
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.07.08 15:51
Оценка: 9 (3)
Здравствуйте, 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 методы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.