Я смотрел на этот вопрос, и мне было любопытно, почему этот deos не компилируется.
Учитывая этот код, кто-нибудь может объяснить, почему вызов IBase.Test()
не разрешаетсяк правильному методу расширения?
public interface IBase { }
public interface IChildA : IBase { }
public interface IChildB : IBase { }
public static class BaseExtensions
{
public static IBase Test(this IBase self) { return self; }
public static T Test<T>(this T self) where T : IChildB { return self; }
}
public static class TestClass
{
public static void Test()
{
IChildA a = null; //Yeh i know its null but just testing for compile here..
IBase firstTry = a.Test(); //Cannot resolve to BaseExtensions.Test(this IBase obj)
IBase secondTry = ((IBase)a).Test(); //Resolves to BaseExtensions.Test(this IBase obj)
IChildB b = null;
IChildB touchedB = b.Test();
}
}
Я получаю ошибку:
Error 166 The type 'IChildA' cannot be used as type parameter 'T' in the generic type or method 'BaseExtensions.Test<T>(T)'. There is no implicit reference conversion from 'IChildA' to 'IChildB'.
У меня было ощущение, что это потому, что это было бы неоднозначно для всего, что реализуетIChildB
и не будет знать, какой метод расширения использовать, но сообщение об ошибке не будет стонать об этой стороне его, и если вы удалите строку IBase firstTry = a.Test();
, то она скомпилируется нормально.