Dlaczego jawne wywołania interfejsu C# w ramach metody ogólnej, która ma ograniczenie typu interfejsu, zawsze wywołują implementację podstawową?Dlaczego jawne wywołania interfejsu dla generycznych zawsze wywołują implementację podstawową?
Rozważmy na przykład następujący kod:
public interface IBase
{
string Method();
}
public interface IDerived : IBase
{
new string Method();
}
public class Foo : IDerived
{
string IBase.Method()
{
return "IBase.Method";
}
string IDerived.Method()
{
return "IDerived.Method";
}
}
static class Program
{
static void Main()
{
IDerived foo = new Foo();
Console.WriteLine(foo.Method());
Console.WriteLine(GenericMethod<IDerived>(foo));
}
private static string GenericMethod<T>(object foo) where T : class, IBase
{
return (foo as T).Method();
}
}
Ten kod generuje następujące:
IDerived.Method
IBase.Method
Zamiast tego, co można by oczekiwać:
IDerived.Method
IDerived.Method
Wydaje się, że nie ma mowy (krótka refleksja), aby wywołać ukryte, bardziej wyraźny pochodzący wdrożenie interfejsu typu zdecydowała w czasie wykonywania.
EDIT: Żeby było jasne, co następuje sprawdzenie, czy wartość true w wywołaniu GenericMethod powyżej:
if (typeof (T) == typeof (IDerived))
Tak więc odpowiedź nie jest taka, że T jest zawsze traktowane jako IBase ze względu na ogólne ograniczenie typu "where T: class, IBase".
Dlaczego powinien nazywać się "IDerived.Method"? Poza tym o tej samej nazwie 'IBase.Method' i' IDerived.Method' nie są powiązane. – PetSerAl
Twój "GenericMethod" określa "IBase"? – mxmissile
Jawna implementacja interfejsu jest * wymagana * tutaj, ponieważ metoda Method() jest niejednoznaczna, są dwa z nich. Jeśli podoba Ci się drugi wynik, lepiej ulepszyć swój projekt. Usuń IBase z IDerived lub usuń Method() z IDerived, ponieważ IBase wymaga już wdrożenia. A * single * Method() w klasie implementuje oba interfejsy bez dwuznaczności. –