2009-06-23 8 views
5

que no entiendo lo que está pasando aquí ...C enumeración de error # boxeo con los genéricos

Tengo el siguiente error: El tipo 'TestApp.TestVal' no se puede utilizar como parámetro de tipo 'T' en el tipo genérico o método 'TestApp.SomeClass<T>'. No hay conversión de boxeo de 'TestApp.TestVal' a 'System.IComparable<TestApp.TestVal>'.

Este error ocurre por el siguiente código:

public enum TestVal 
{ 
    First, 
    Second, 
    Third 
} 

public class SomeClass<T> 
    where T : IComparable<T> 
{ 
    public T Stored 
    { 
     get 
     { 
      return storedval; 
     } 
     set 
     { 
      storedval = value; 
     } 
    } 
    private T storedval; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     //Error is on the next line 
     SomeClass<TestVal> t = new SomeClass<TestVal>(); 
    } 
} 

Dado que la enumeración es un int por defecto y int de implementar la interfaz IComparable<int> parece que no debería haber un error ....

+0

de int IComparable pero eso no quiere decir RandomEnumType implementa IComparable . – AakashM

Respuesta

8

En primer lugar, no estoy seguro de si es sensato usar IComparable<T> con una enumeración ... IEquatable<T>, seguro, pero ¿comparación?

Como una alternativa más segura; en lugar de ordenar el IComparable<T> con la restricción genérica, tal vez use Comparer<T>.Default dentro de la clase. Esto tiene la ventaja de admitir IComparable<T> y IComparable, y significa que tiene menos restricciones para propagarse.

Por ejemplo:

public class SomeClass<T> { // note no constraint 
    public int ExampleCompareTo(T other) { 
     return Comparer<T>.Default.Compare(Stored, other); 
    } 
    ... [snip] 
} 

Esto funciona bien con la enumeración:

SomeClass<TestVal> t = new SomeClass<TestVal>(); 
t.Stored = TestVal.First; 
int i = t.ExampleCompareTo(TestVal.Second); // -1 
+0

Gracias por la posible solución alternativa a mi problema. El código real es muy profundo en un marco de prueba que necesita manejar casi cualquier tipo de datos de prueba. Tendré que investigar un poco más, pero parece que tu código podría ser una mejor forma de lidiar con la comparación en mis objetos genéricos ... –

+0

¡Genial truco, gracias! –

0

En las enumeraciones C# implementa IComparable, pero no el genérico IComparable<T>. No estoy seguro de por qué esto es así, pero tal vez podría cambiar al IComparable no genérico en su cláusula where.

5

Las enumeraciones no derivan de System.Int32s - derivan de System.Enum, que no implementa IComparable<int> (sin embargo, implementa IComparable).

Aunque el valor subyacente de una enume es int por defecto, la enumeración en sí no lo es. Por lo tanto, no hay conversión entre los dos.

+0

(Arreglé el descuento, y luego me volví loco y edité tu respuesta en lugar de la mía! Solucionado ahora; perdón por eso ...) –

+0

Gracias por la explicación. Eso ayuda. También me hace preguntarme si tendré el mismo tipo de problema con las estructuras ... –

0

Enum no implementa IComparable<T>, pero sí implementa IComparable. Así que una enumeración puede ser la T en una cláusula where como:

where T : IComparable 

pero esto da un error:

where T : IComparable<T> 

Y luego supongo que desea SomeClass ser comparables. Para hacer eso, tendría que implementar IComparable en sí mismo.

He aquí un ejemplo de ambos (el uso de un miembro del público para mantener el código simple): Implementar

public class SomeClass<T> 
    : IComparable<SomeClass<T>> 
    where T : IComparable 
{ 
    public T storedval; 

    public int CompareTo(SomeClass<T> other) 
    { 
     return storedval.CompareTo(other.storedval); 
    } 
} 
Cuestiones relacionadas