2009-06-23 15 views
5

non capisco cosa sta succedendo qui ...C errore enum # boxe con i generici

ho ottenuto il seguente errore: Il tipo 'TestApp.TestVal' non può essere utilizzato come tipo di parametro 'T' nel tipo generico o metodo 'TestApp.SomeClass<T>'. Non è prevista la conversione di boxe da 'TestApp.TestVal' a 'System.IComparable<TestApp.TestVal>'.

Questo errore si verifica per il seguente codice:

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

Dal momento che l'enum è un int per impostazione predefinita e int di implementare l'interfaccia IComparable<int> sembra che non ci dovrebbe essere un errore ....

+0

di int implementare IComparable ma questo non significa che RandomEnumType implementa IComparable . – AakashM

risposta

8

In primo luogo, non sono sicuro se sia ragionevole utilizzare IComparable<T> con un enum ... IEquatable<T>, sicuro - ma il confronto?

Come alternativa più sicura; piuttosto che mandare il IComparable<T> con il vincolo generico, forse usare Comparer<T>.Default all'interno della classe. Questo ha il vantaggio di supportare IComparable<T> e IComparable - e significa che ci sono meno vincoli da propagare.

Ad esempio:

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

Questo funziona bene con l'enumerazione:

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

Grazie per l'eventuale soluzione alternativa al mio problema. Il codice attuale è molto profondo in un framework di test che deve gestire praticamente qualsiasi tipo di dati di test. Dovrò fare qualche altra indagine ma sembra che il tuo codice potrebbe essere un modo migliore per gestire il confronto nei miei oggetti generici .... –

+0

Cool trick thanks !! –

0

Nelle enumerazioni C# implementare IComparable, ma non il generico IComparable<T>. Non sono sicuro del motivo, ma forse potresti passare alla versione non generica IComparable nella clausola where.

5

Le enumerazioni non derivano da System.Int32s - derivano da System.Enum, che non implementa IComparable<int> (tuttavia implementa IComparable).

Sebbene il valore sottostante di un enum sia un valore predefinito, l'enum in sé non lo è. Quindi, non c'è conversione tra i due.

+0

(Ho corretto il markdown - e poi sono diventato pazzo e ho modificato la tua risposta invece della mia! Risolto ora, mi dispiace per quello ...) –

+0

Grazie per la spiegazione. Questo aiuta. Mi fa anche chiedere se avrò lo stesso tipo di problema con le strutture .... –

0

Enum non implementa IComparable<T>, ma non implementa IComparable. Così un enum può essere il T in una clausola WHERE come:

where T : IComparable 

ma questo dà un errore:

where T : IComparable<T> 

E poi suppongo vuoi SomeClass essere comparabili. Per fare ciò, dovrebbe implementare IComparable stesso.

Ecco un esempio di entrambi (utilizzando un membro pubblico per mantenere il codice semplice):

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

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