2010-06-06 13 views
5

Tengo dos clases, una clase base y una clase secundaria. En la clase base que definen un método virtual genérica:Error raro de compilación de genéricos

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

Luego, en mi clase de niño que trato de hacer esto:

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

Visual Studio le da a este extraño error:

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'.

Repetir la cláusula where en la anulación del hijo también da un error:

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

Entonces, ¿qué estoy haciendo mal aquí?

+0

¿Debería ser 'protegido anular BarChild Foo ()'? ¿Puedes dar nombres propios? Foo y Bar me lastimaron la cabeza. – Kobi

+0

¿Y no debería ser base de devolución.Foo como BarChild() ;? – GenericTypeTea

+1

Su código tiene todo tipo de problemas (por ejemplo, su método reemplazado le falta su parámetro genérico, su declaración de retorno tiene parens en el lugar equivocado, etc.). Es más probable que obtenga respuestas útiles si crea una reproducción mínima de su problema que tenga solucionados todos los problemas obvios. – kvb

Respuesta

3

Esto funciona. Había que hacer el tipo de retorno genérica:

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>(); 
} 

Estos son algunos básica C# override rules:

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

Esto significa que el mismo tipo de retorno y los mismos argumentos del método.

+0

¿Puedes editar 1 vez más? las clases deben sangrar para formatear correctamente AFAICT –

+0

Vaya, corregido. –

2

Su sustitución no puede cambiar el tipo de devolución, incluso si el tipo de devolución deriva del tipo de devolución del método de clase base. Tienes que hacer algo como lo hizo Igor anteriormente, y hacer que el tipo de devolución sea genérico.