2012-10-18 16 views
9

Sto provando a scrivere un metodo di estensione per Enumerazione nullable.
Come con questo esempio:Metodo di estensione per nullaum enum

// ItemType is an enum 
ItemType? item; 
... 

item.GetDescription(); 

Così ho scritto questo metodo che non viene compilato per qualche ragione che non capisco:

public static string GetDescription(this Enum? theEnum) 
{ 
    if (theEnum == null) 
     return string.Empty; 

    return GetDescriptionAttribute(theEnum); 
} 

sto ottenendo il seguente errore su Enum? :

solo non annullabile tipo di valore potrebbe essere sottostante dei System.Nullable

Perché? Enum non può avere il valore null!

Aggiornamento:

Se hanno un sacco di enumerazioni, ItemType è solo un esempio di uno di loro.

risposta

17

System.Enum è un class, quindi basta cadere il ? e questo dovrebbe funzionare.

(Con "questo dovrebbe funzionare", voglio dire, se si passa in un null-valore ItemType?, si otterrà un nullEnum nel metodo.)

public static string GetDescription(this Enum theEnum) 
{ 
    if (theEnum == null) 
     return string.Empty; 
    return GetDescriptionAttribute(theEnum); 
} 
enum Test { blah } 

Test? q = null; 
q.GetDescription(); // => theEnum parameter is null 
q = Test.blah; 
q.GetDescription(); // => theEnum parameter is Test.blah 
+0

http://msdn.microsoft.com/en-us/library/system.enum.aspx – Jacek

+0

@Jacek Cosa intendi? – Rawling

+0

@Jacek: stavo per scriverlo, ma l'ho provato e, sorprendentemente, funziona. – Jens

0

Forse è meglio aggiungere valore in più al vostro enum e chiamare nulla :)

+1

Sì, sono d'accordo, un Enum con uno dei suoi valori "Undefined" o "Null" o qualcosa avrebbe più senso. Oppure potresti avvolgere il tuo enum in una classe e renderlo nullo se volessi davvero un valore nullo. –

+2

Eh? L'esatto opposto è vero - solo i tipi di valore possono essere usati con 'Nullable '. E come è rilevante "Inullable"? –

+0

L'enum null non è un'opzione. non in asp.net-MVC – gdoron

3

È consigliabile utilizzare il tipo enum reale nella vostra firma del metodo:

public static string GetDescription(this ItemType? theEnum) 

System.ValueType e System.Enum non sono trattati come tipi di valore (solo i tipi derivati ​​da essi), quindi sono annullabili (e non è necessario specificarli come valori nulli). Provalo:

// No errors! 
ValueType v = null; 
Enum e = null; 

Si potrebbe anche provare questa firma:

public static string GetDescription<T>(this T? theEnum) where T: struct 

permette a questo anche struct s, però, che potrebbe non essere ciò che si desidera. Penso di ricordare alcune librerie che aggiungono un vincolo di tipo di enum dopo la compilazione (C# non lo consente). Solo bisogno di trovarlo ...

EDIT: Trovato esso:

http://code.google.com/p/unconstrained-melody/

+0

Se hanno un sacco di enumerazioni, 'ItemType' è solo un esempio. Ero sicuro che fosse ovvio, mi dispiace. – gdoron

+0

Ohh, la seconda parte che hai aggiunto risponde alla mia domanda, grazie. Ma c'è un modo per superare questo strano design? – gdoron

+0

È possibile utilizzare un vincolo generico, ma C# non consente di specificare enum come vincolo. Vedi la mia modifica per una soluzione. – Botz3000

1

Si può semplicemente fare il vostro metodo di estensione generico:

public static string GetDescription<T>(this T? theEnum) where T : struct 
{ 
    if (!typeof(T).IsEnum) 
     throw new Exception("Must be an enum."); 

    if (theEnum == null) 
     return string.Empty; 

    return GetDescriptionAttribute(theEnum); 
} 

Purtroppo, non è possibile utilizzare System.Enum in un vincolo generico, in modo che il metodo di estensione mostrerà per tutti i valori Null (da qui il controllo in più).

+0

Questo è bello perché evita la boxe. Puoi anche dire "! TheEnum.HasValue" se preferisci. Se qualcuno è interessato al vincolo generico a 'System.Enum', leggi anche [Vincoli generici per enumerati e delegati] (https://msmvps.com/blogs/jon_skeet/archive/2009/09/10/generic-constraints-for -enums-e-delegates.aspx). –

Problemi correlati