2010-06-06 2 views
5

У меня есть два класса, базовый класс и дочерний класс. В базовом классе я определить общий виртуальный метод:Ошибка компиляции Weird generics

protected virtual ReturnType Create<T>() where T : ReturnType {}

Тогда в моем классе ребенка я пытаюсь сделать это:

protected override ReturnTypeChild Create<T>() // ReturnTypeChild inherits ReturnType 
{ 
    return base.Create<T> as ReturnTypeChild; 
}

Visual Studio предоставляет эту странную ошибку:

The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Create()'. There is no boxing conversion or type parameter conversion from 'T' to 'ReturnType'.

Повторение предложения where при переопределении ребенка также дает ошибку:

Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly

Так что я делаю неправильно здесь?

+0

Должно ли это быть защищено переопределением BarChild Foo () '? Можете ли вы назвать имена? Фу и Бар повредили мне голову. – Kobi

+0

И не должно быть возврата base.Foo как BarChild() ;? – GenericTypeTea

+1

У вашего кода есть всевозможные проблемы (например, в вашем переопределенном методе отсутствует его общий параметр, ваш оператор возврата имеет парсеры в неправильном месте и т. Д.). У вас больше шансов получить полезные ответы, если вы создадите минимальное воспроизведение вашей проблемы, в которой исправлены все очевидные проблемы. – kvb

ответ

3

Это работает. Вы должны были сделать тип возвращаемого родовое:

public class BaseClass { 
    public virtual T Create<T>() where T : BaseClass, new() { 
    var newClass = new T(); 
    //initialize newClass by setting properties etc 
    return newClass; 
    } 
} 

public class DerivedClass : BaseClass { 
    public override T Create<T>() { 
    var newClass = base.Create<T>(); 
    //initialize newClass with DerivedClass specific stuff 
    return newClass; 
    } 
} 

void Test() { 

DerivedClass d = new DerivedClass() ; 
d.Create<DerivedClass>(); 
} 

Это некоторые основные C# override rules:

The overridden base method must have the same signature as the override method.

Это означает, что один и тот же тип возвращаемого значения и те же аргументы метода.

+0

вы можете отредактировать еще 1 раз? классы должны иметь отступы для правильного форматирования AFAICT –

+0

Упс, исправлено. –

2

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

Смежные вопросы