Как возвратить подтип в переопределенном методе подкласса в C#?

Статично типизированный тип проверки типов во время компиляции и тип не может измениться. [Нельзя получать симпатичные комментарии комментариев к типу, создается новая переменная / ссылка).

Динамическая типизация типов языков во время выполнения и тип переменной CAN могут быть изменены при запуске, время.

29
задан recursive 7 January 2009 в 20:20
поделиться

7 ответов

К сожалению, не ковариантные типы возврата не поддерживаются в C# для переопределения метода. (Так же контравариантные типы параметра.)

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

(РЕДАКТИРОВАНИЕ: Marc имеет разумное решение - хотя это довольно ужасно, и сокрытие метода обычно является плохой вещью для удобочитаемости. Никакое предназначенное преступление, Marc;)

я верю , это - на самом деле ограничение CLR, не только язык один - но и я мог быть неправым.

(Как историю, Java (язык) имел то же ограничение до 1.5 - но это получило ковариантность в то же время, что и дженерики.)

18
ответ дан Community 14 October 2019 в 08:15
поделиться

Вы могли сделать класс универсальным, если это не делает беспокоит Вас:

    class BaseReturnType { }
    class DerivedReturnType : BaseReturnType { }

    abstract class BaseClass<T> where T : BaseReturnType
    {
        public abstract T PolymorphicMethod();
    }

    class DerivedClass : BaseClass<DerivedReturnType>
    {
        // Error: return type must be 'BaseReturnType' to match 
        // overridden member 'BaseClass.PolymorphicMethod()'
        public override DerivedReturnType PolymorphicMethod()
        {
            return new DerivedReturnType();
        }
    }
17
ответ дан Stormenet 14 October 2019 в 08:15
поделиться

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

Первый, добавьте новый метод к своему производному классу, который возвратит значение с корректным типом. Во-вторых, отметьте метод переопределения не - переопределяемый и имейте его делегат в Вашем новом методе.

Вот именно. Вы решили свою проблему. Дочерние классы не будут в состоянии повторно развернуть тип, потому что они должны переопределить Ваш новый метод.

я приношу извинения, если код не совершенно правилен; я привык к VB.net.

abstract class C1 {
    public abstract IEnumerable<Byte> F1();
}
class C2 : C1 {
    public sealed override IEnumerable<Byte> F1() {
        Return F2();
    }
    public overridable IList<Byte> F2() {
        Return {1, 2, 3, 4};
    }
}
2
ответ дан Craig Gidney 14 October 2019 в 08:15
поделиться

Можно сделать это при представлении дополнительного метода для переопределения (так как Вы не можете override и new метод с тем же именем в том же типе):

abstract class BaseClass
{
    public BaseReturnType PolymorphicMethod()
    { return PolymorphicMethodCore();}

    protected abstract BaseReturnType PolymorphicMethodCore();
}

class DerivedClass : BaseClass
{
    protected override BaseReturnType PolymorphicMethodCore()
    { return PolymorphicMethod(); }

    public new DerivedReturnType PolymorphicMethod()
    { return new DerivedReturnType(); }
}

Теперь Вы имеете PolymorphicMethod метод на каждом уровне с корректным типом.

12
ответ дан Marc Gravell 14 October 2019 в 08:15
поделиться
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }

abstract class BaseClass {
    public abstract BaseReturnType PolymorphicMethod();
}

class DerivedClass : BaseClass {
    // Error: return type must be 'BaseReturnType' to match 
    // overridden member 'BaseClass.PolymorphicMethod()'
    public override BaseReturnType PolymorphicMethod() { 
        return new DerivedReturnType(); 
    }
}

это должно работать

1
ответ дан anand 14 October 2019 в 08:15
поделиться

Измените свою сигнатуру метода на Производном классе к:

 public override BaseReturnType PolymorphicMethod() 
 {
    return new DerivedReturnType();     
 }

C# не поддерживает различные типы возврата. Можно проверить это сообщение для способа сделать это использование Дженерики... http://srtsolutions.com/blogs/billwagner/archive/2005/06/17/covaraint-return-types-in-c.aspx

Вот является демонстрационное использование Дженериками в Вашей модели:

public class BaseReturnType
{
}
public class DerivedReturnType : BaseReturnType
{
}

public abstract class BaseClass<T> where T : BaseReturnType
{
    public abstract T PolymorphicMethod();

}

public class DerviedClass : BaseClass<DerivedReturnType>
{
    public override DerivedReturnType PolymorphicMethod()
    {
        throw new NotImplementedException();
    }
}
1
ответ дан JoshBerke 14 October 2019 в 08:15
поделиться

Мне кажется, что необходимо возвращать интерфейс, не базовый класс.

0
ответ дан Greg Hurlman 14 October 2019 в 08:15
поделиться
Другие вопросы по тегам:

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