2011-04-05 27 views
14

Tengo dos clases base genéricas. La segunda clase genérica tiene una restricción en su parámetro de la primera clase.Genéricos con parámetros genéricos y clase abstracta

abstract class FirstClass<T> {...} 

abstract class SecondClass<U> where U : FirstClass {...} 

Esto no funciona, porque FirstClass no está definido. Entonces necesito hacer esto.

abstract class FirstClass<T> {...} 

abstract class SecondClass<U, T> where U : FirstClass<T> {...} 

Que funciona. Sin embargo, esto hace que la implementación de estas clases abstractas sea desagradable.

class SomeClass {...} 

class MyFirstClass : FirstClass<SomeClass> {...} 

class MySecondClass : SecondClass<MyFirstClass, SomeClass> {...} 

Esto me parece redundante porque estoy especificando SomeClass dos veces. ¿Hay alguna forma de declararlo de forma que T de FirstClass sea automáticamente la U de SecondClass? Lo que realmente me gustaría que se vea así es.

class SomeClass {...} 

class MyFirstClass : FirstClass<SomeClass> {...} 

class MySecondClass : SecondClass<MyFirstClass> {...} 

Aunque dudo que este escenario exacto sea posible, ¿hay un limpiador de qué hacer lo que estoy tratando de hacer?

Editar

Varias personas han sugerido hacer una interfaz de IFirstClass. Pero mis definiciones están más cerca de esto.

class FirstClass<T> 
{ 
    public T MyObj { get; set; } 
} 

class SecondClass<U, T> where U : FirstClass<T> 
{ 
    U MyFirstClass { get; set; } 
} 

Con una interfaz no puedo acceder a MyFirstClass.MyObj desde SecondClass. Si bien podría crear un object T MyObj { get; set; } en IFirstClass, entonces use new para ocultarlo, silverlight arroja un ajuste en el enlace si hago esto.

+0

Aunque no menciono Silverlight en la pregunta, este es un proyecto Silverlight. No estoy seguro de si esto restringiría la solución. – cadrell0

+0

Limitaría la solución si intentara ordenar TypeOf de WCF RIA Services como sus clases de POCO, ya que los genéricos no pueden exponerse como WCF o WCF RIA Services (sin algunas soluciones importantes). –

+0

¿Está utilizando algún tipo de información específica sobre FirstClass ? Si no, lo que tiendo a hacer en estas instancias es hacer que FirstClass coincida con alguna interfaz IGenericFirstClass y luego especifique la restricción como IGenericFirstClass. Oculta la dependencia de tipo U. –

Respuesta

4

Si realmente está usando los argumentos de tipo genérico a FirstClass (ya que, según su edición, parece que lo es), entonces no, lo que está buscando desafortunadamente no es posible. El compilador no diferencia entre los argumentos de tipo que están relacionados y los que no.

+1

Eso es lo que pensé, pero ¿qué tenemos si no tenemos esperanza? – cadrell0

+0

@ cadrell0: careers.stackoverflow.com;) En serio, no olvides aceptar una de estas respuestas. Estas son prácticamente tus únicas opciones. –

10

En mi experiencia, es más fácil crear una interfaz no genérica para clases genéricas. También resuelve el problema cuando necesitas lanzar a la clase base sin saber el tipo genérico.

interface IFirstClass {...} 

abstract class FirstClass<T> : IFirstClass {...} 

abstract class SecondClass<T> where T : IFirstClass {...} 
+0

Por favor, mira mis ediciones. No me he encontrado con un problema en el que necesite lanzar a la clase base. – cadrell0

2

Cree una interfaz que implemente FirstClass. Entonces puede restringir SecondClass a la interfaz.