2008-10-24 13 views
7

I tienen clase A:contraints genéricas en las clases derivadas

public class ClassA<T> 

Clase B se deriva de A:

public class ClassB : ClassA<ClassB> 

Clase C se deriva de la clase B:

public class ClassC : ClassB 

ahora tengo un método genérico con limitaciones

public static T Method<T>() where T : ClassA<T> 

OK, ahora quiero llamar:

ClassC c = Method<ClassC>(); 

pero me sale el error de compilación diciendo: Type argument 'ClassC' does not inherit from or implement the constraint type 'ClassA<ClassC>.

Sin embargo, el el compilador permitirá:

ClassB b = Method<ClassB>(); 

Mi entendimiento es que esta falla porque ClassC hereda ClassA<ClassB> en lugar de ClassA<ClassC>

Mi verdadera pregunta es, ¿es posible crear una clase que deriva de ClassB que se puede utilizar de alguna manera con el método genérico?

Esto puede parecer que los genéricos se usan en exceso y estoy de acuerdo. Estoy intentando crear objetos de capa empresarial derivados de los objetos de datos subsónicos en un proyecto separado.

Nota: He puesto el < T> con espacios adicionales, de lo contrario se desvincularán de la pregunta.

Respuesta

5

Bueno, se podría cambiar el método a:

public static T Method<T,U>() where T : ClassA<U> where U : T 

¿Eso ayuda en absoluto? No sirve de mucho si no puede cambiar el Método, por supuesto ...

+0

Sí, esto resuelve el problema. El método es en realidad: DB.Get < T > (cadena primaryColumnValue) T utilizado para devolver un objeto de datos de la base de datos. Parece que cada vez es más complicado que sea necesario ... Tengo que dar un paso atrás y volver a pensar en la arquitectura. – ptutt

2

No. Debe cambiar o ajustar este método.

Aquí está el motivo.

ClassC hereda de ClassB que hereda de claseA (ClassB)

ClassC no hereda de claseA (ClassC)

Ningún hijo de ClassB heredará del claseA (clase hija), porque en vez heredan de ClassB y ClassB no heredan de ClassA (clase infantil).

Generic types are invariant.

1

En la mayoría de los casos es posible resolver esta situación por tener una base de clase abstracta no genérico:

public abstract class BasicClassA 
{ 
} 

public class ClassA<T> : BasicClassA 
{ 
} 

public class ClassB : ClassA<ClassB> 
{ 
} 

public class ClassC : ClassB 
{ 
} 

public static T Method<T>() where T : BasicClassA 
{ 
    return null; 
} 

Su kilometraje puede variar, sin embargo.

+0

En este caso, esta sugerencia no resuelve el escenario porque dentro de "Método" se invocan métodos en ClassA que devuelven tipo T. Gracias por la sugerencia. – ptutt

Cuestiones relacionadas