Почему этот универсальный метод расширения не компилируется?

Код немного странный, так что несите меня (имейте в виду, что этот сценарий действительно появился в производственном коде).

Скажем, у меня есть такая структура интерфейса:

public interface IBase {  }
public interface IChild : IBase {  }

public interface IFoo<out T> where T : IBase {  }

С помощью этого класса метода расширения, построенного вокруг интерфейсов:

public static class FooExt
{
    public static void DoSomething<TFoo>(this TFoo foo)
        where TFoo : IFoo<IChild>
    {
        IFoo<IChild> bar = foo;

        //foo.DoSomethingElse();    // Doesn't compile -- why not?
        bar.DoSomethingElse();      // OK
        DoSomethingElse(foo);       // Also OK!
    }

    public static void DoSomethingElse(this IFoo<IBase> foo)
    {
    }
}

Почему закомментированная строка в DoSomething не компилируется? Компилятор с радостью разрешил мне назначить foo на bar , который относится к тому же типу, что и общее ограничение, и вместо этого вызвать метод расширения для него. Также нет проблем вызвать метод расширения без синтаксиса метода расширения.

Кто-нибудь может подтвердить, является ли это ошибкой или ожидаемым поведением?

Спасибо!

Просто для справки, вот ошибка компиляции (типы сокращены для разборчивость):

'TFoo' не содержит определения для 'DoSomethingElse', и лучшая перегрузка метода расширения 'DoSomethingElse (IFoo)' имеет некоторые недопустимые аргументы

37
задан Cameron 9 June 2011 в 14:42
поделиться