2011-02-02 10 views
5

Tengo las siguientes clases y yo estoy tratando de llamar a comparar el método de la clase ExportFileBaseBL pero me sale el errorC# genéricos - pidiendo método genérico de una clase genérica

No se puede convertir implícitamente el tipo 'Clase 1' a 'T' . existe una conversión explícita (¿falta un yeso?)

public abstract class Class1<T> where T: Class2 
{ 
    public abstract Class1<T> Compare(Class1<T> otherObj); 
} 

public abstract class Class3<T, U> where T: Class1<U> 
         where U: Class2 
{ 
    public T Compare(T obj1, T obj2) 
    { 
     if (obj1.Prop1 > obj2.Prop1) 
     { 
      return obj1.Compare(obj2); // Compiler Error here 
     } 
     else 
     { 
      return obj2.Compare(obj1); // Compiler Error here 
     } 
    } 

} 

No debería la conversión de tipo implícito? ¿Me estoy perdiendo de algo?

Respuesta

4

El problema es que su método abstracto Compare está definido para aceptar un parámetro de tipo Class1<T> y devolver una instancia de Class1<T>, no es tipo más específico que Class1<T>. Pero esto es lo que su método Class3.Compare está intentando hacer: llame al T.Compare y suponga que la salida será un T, cuando de hecho solo puede estar seguro de que será un Class1<U>.

para proporcionar un ejemplo más comprensible sencillo, supongamos que tenía esta clase:

class Parser 
{ 
    public abstract object Parse(string text); 
} 

class Int32Parser 
{ 
    public int Parse(Parser parser, string text) 
    { 
     return parser.Parse(text); 
    } 
} 

El código anterior hace una suposición errónea similar a la suya: que parser.Parse devolverá un int sólo porque int deriva de object (al igual que en su caso, T debe derivar de Class1<U>); de hecho, solo puede estar seguro de que devolverá un object.

Hay dos maneras en que puedo ver de solucionar este problema: hacer Class1<T>.Compare un método genérico:

public abstract U Compare<U>(U otherObj) where U : Class1<T>; 

... o relajarse la especificidad tipo de valor de retorno a su Class3.Compare del método:

public Class1<U> Compare(T obj1, T obj2) 
{ 
    // ... 
} 

Personalmente, preferiría el segundo a menos que necesites el primero. Todas estas restricciones de tipo genérico pueden volverse muy complicadas y cargarle más de lo que espera cuando la complejidad comienza a crecer así.

+0

Gracias Dan, eso responde mi pregunta. – logik6

+0

Jup jup, ahora que hemos agregado una actualización sobre el método de comparación, estoy de acuerdo con la respuesta. – jcolebrand

2

Llame el método con el tipo de parámetro que declara en su nivel de clase.

return obj1.Compare<T>(obj2); 

Tendrá que hacer que la definición del método de comparación genérica así:

public abstract Class1<T> Compare<T>(Class1<T> otherObj); 
+1

El método de comparación no es genérico, por lo que no aceptará un parámetro de tipo en su forma actual. –

+0

Pero @Kyle solo ilustra dónde se debe corregir en el código padre. También necesita agregar un '' al método de comparación de primera clase. – jcolebrand

+0

Eso debería agregarse a la respuesta entonces. Lo agregaré –

Cuestiones relacionadas