Вопрос по c# – Почему реализация интерфейса не может возвращать более определенный тип?

28

Если интерфейс указывает свойство или метод для возврата другого интерфейса, то почему в реализациях первого интерфейса не допускается «изменение»? тип возвращаемого значения в более конкретный тип?

Давайте возьмем пример, чтобы проиллюстрировать:

interface IFoo
{
    IBar GetBar();
}
interface IBar
{ }

class Foo : IFoo
{
    // This is illegal, we are not implementing IFoo properly
    public Bar GetBar()
    {
        return new Bar();
    }
}

class Bar : IBar
{ }

I know как заставить это работать, этоnot моя забота.

Я могу просто либо:

Change return type of GetFoo() to IBar, or Explicitly implement the interface and just call GetBar from the IFoo.GetBar() method

Что я действительно спрашиваю, так это причины не просто компилировать приведенный выше код. Имеется ли случай, когда вышеизложенное не выполняет договор, указанныйIFoo.

Я чувствую, что комментарий BrainSlugs83 здесь является ответом, поскольку он обеспечивает достойный обходной путь. carlin.scott
Существует третий способ, который немного более удобен, чем вышеупомянутые два. Вы можете реализовать интерфейс с абстрактным классом. А потом, в вашем "конкретном" Класс наследует абстрактный класс вместо интерфейса. Тогда в вашем "конкретном" класс, вы можете скрыть базовые методы с помощью & quot; new & quot; ключевое слово. Это работает прилично для меня. BrainSlugs83

Ваш Ответ

2   ответа
18

Обычно я бы сказал, что это было бы в случае сбалансирования выгоды с добавленной сложностью поддержки такой функции. (Все функции требуют усилий для разработки, документирования, реализации, тестирования, а затем разработчики должны быть проинформированы о них.) Обратите внимание, что могут возникнуть некоторые существенные сложности, если вы хотите поддержать возврат типа значения, который реализовал интерфейс, например (как это заканчивается в другом представлении, а не просто ссылка).

В этом случае я неbelieve CLR даже поддерживает такую функцию, что делает C # очень трудным сделать это чисто.

Я согласен, что это была бы полезная функция, но я подозреваю, что она не была сочтена достаточно полезной, чтобы требовать дополнительной работы.

Error: User Rate Limit ExceededallError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededrequiredError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededbase.Foo()Error: User Rate Limit Exceededdynamic.
5

Функция, о которой вы спрашиваете, называется"return type covariance", Как указанов ВикипедииИ Java, и C ++ имеют его, что, возможно, удивляет, что в C # его нет.

Эрик Липперт подтверждает в комментариях к этому ответу, что эта функция не была реализована, поскольку она не стоила усилий по реализации. (В предыдущей редакции этого ответа ответственность за это решение была возложена на Эрика лично; он говорит, что это неверно, и что если кто-то несет ответственность, то это был Андерс Хейлсберг.)

Несмотря на это, сейчас есть различные предложения, чтобы добавить его в язык (см.https://github.com/dotnet/roslyn/issues/357, https://github.com/dotnet/csharplang/blob/master/proposals/covariant-returns.md, https://github.com/kingces95/coreclr/issues/2), так что, возможно, он будет реализован в ближайшие пару лет. В соответствии с этими обсуждениями не похоже, что существуют какие-либо глубокие причины, по которым эта функция не должна существовать в C #in principle скорее, это просто никогда не оценивалось как стоящее чьих-либо усилий для реализации.

Error: User Rate Limit ExceededAndersError: User Rate Limit Exceeded

Похожие вопросы