Интерфейсы C # и маскировка типов - PullRequest
3 голосов
/ 17 декабря 2009

Мои подклассы не могут маскироваться под базовый класс при удовлетворении требований интерфейса. Например:

class MyBaseClass
{}

class MySubClass : MyBaseClass
{}

interface MyInterface
{
    MyBaseClass someFunction();
}

class MyImplementation : MyInterface
{
    public MySubClass someFunction() { return null; }
}

Генерирует следующую ошибку:

«MyNamespace.MyImplementation» не реализует элемент интерфейса «MyNamespace.MyInterface.someFunction ()». «MyNamespace.MyImplementation.someFunction ()» не может реализовать «MyNamespace.MyInterface.someFunction ()», поскольку у него нет соответствующего возвращаемого типа «MyNamespace.MyBaseClass».

Это также проблема с требованием интерфейсов против реализаций. Например, если у меня есть интерфейс с функцией, которая возвращает IList, моя реализация не может вернуть List - она ​​ДОЛЖНА вернуть IList.

Я что-то не так делаю или это ограничение интерфейсов C #?

Ответы [ 4 ]

4 голосов
/ 17 декабря 2009

C # не поддерживает ковариантные типы возврата. При реализации интерфейса вы должны вернуть тип, указанный интерфейсом. Если вы хотите, вы можете явно реализовать интерфейс и иметь другой метод с тем же именем, который возвращает подтип. Например:

class MyImplementation : MyInterface
{
    MyBaseClass MyInterface.someFunction() { return null; }
    public MySubClass someFunction() { return null; }
}
2 голосов
/ 17 декабря 2009

Подписи должны точно совпадать, вы должны сделать:

class MyImplementation : MyInterface
{
    public MyBaseClass someFunction() { return null; }
}

Вы можете реализовать дженерики, хотя бы так:

interface MyInterface<T>
{
    T someFunction();
}

class MyImplementation : MyInterface<MySubClass>
{
    public MySubClass someFunction() { return null; }
}

Примечание. Возможно, мне не хватает какого-либо синтаксиса, например MyInterface.someFunction

1 голос
/ 17 декабря 2009

Если интерфейс ожидает MyBaseClass, вам нужно указать этот тип. Вы можете выполнить приведение экземпляра MySubClass и вернуть его обратно при получении.

0 голосов
/ 17 декабря 2009

MyImplementation явно не реализует этот интерфейс; метод, который возвращает MySubClass, отличается от метода, который возвращает MyBaseClass, независимо от того, являются ли они связанными классами.

То же самое верно для вашего примера List / IList, я не могу понять, почему вы считаете это слабостью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...