2010-06-04 22 views
5

Utilizzo di VS2010 e .net V4.0 Vorrei ottenere quanto segue:Valori delle stringhe C# come valori delle stringhe Enum?

Ho già 2 file di risorse nel mio progetto per 2 lingue: inglese e ceco.

devo dire Resource Management in .net è eccellente, io sono sorpreso anche per ottenere il completamento del codice in sede di attuazione di una stringa, ad esempio:

string desc = Strings.ResourceManagerDesc 

Questo ottiene la stringa associata con l'attuale cultura del thread.

Ora sto cercando di creare un Enum che può avere la parte String dell'Enum interpretata dalle risorse di Stringhe. Nel modo seguente (Questo codice non funziona):

public enum DownloadStatus 
{ 
1 = Strings.DownloadState_Complete, 
2 = Strings.DownloadState_Failed, 
3 = Strings.DownloadState_InProgress 
} 

questo è un esempio fatta, ma si può vedere il punto qui. Dal momento che il codice sopra non funzionerà, c'è un modo migliore per ottenere ciò che voglio?

+0

Che cosa stai cercando di ottenere esattamente? –

+0

@Robert, diciamo che avevo un tipico enum contenente i valori pronti, impostati, vai - ora quando eseguo un myEnum.ToString() ottengo il valore stringa pronto, impostato, stampato (dipende se enum è 1,2 , 3). Quello che sto cercando di fare è localizzare questo valore di stringa in base alla cultura, l'Enum.ToString dovrebbe stampare il valore in base alla cultura corrente. –

+0

@JL ha aggiunto una risposta che localizza un enum. Si noti che non è possibile localizzare le stringhe enum con Enum.ToString(), ma è possibile ottenere la localizzazione tramite un metodo per convertire un enum in una stringa di risorse, che è possibile recuperare dalle risorse. –

risposta

8

Questa domanda è vecchia ma non ha una risposta accettata e stavo cercando un buon modo per farlo.

Ecco quello che ho fatto, ho costruito una proroga per la mia Enum in modo che restituisca un valore dalla Resource Manager:

public enum EventType 
    { 
     NewVersion = 1, 
     Accepted = 2, 
     Rejected = 3, 
     BruteForce = 4 
    } 

    public static class EventTypeExtension 
    { 
     public static string Display(this EventType type) 
     { 
      return Strings.ResourceManager.GetString("EventType_" + type); 
     } 
    } 

Spero che questo possa aiutare qualcuno!

1

Le enumerazioni vengono compilate come parte dell'assembly. Assegnare essenzialmente un metodo al valore dell'enumerazione non è un valore costante: il CLR non è abbastanza intelligente per calcolare il valore in fase di compilazione, deve essere una costante.

Suggerirei di creare un enum diverso per ogni lingua (dimenticare le risorse) e utilizzare una classe di supporto per restituire quella corretta in base al contesto di langauge necessario.

+0

Ad ogni modo di avere una risorsa statica? –

+0

Penso che questo sia il nocciolo della questione, nessun compito dinamico, non importa quale (risorsa o qualsiasi altro campo dinamico). Quindi immagino che Enum sia lo strumento sbagliato per il lavoro in questo caso. –

+0

Ma questo sarebbe ancora il comportamento di runtime - non compilare il tempo per l'enum. –

1

Le enum non possono ereditare dalle stringhe. Nel codice non è necessario preoccuparsi della lingua del codice, quindi il tuo enum può semplicemente contenere gli stati rilevanti.

Sembra che quello di cui hai bisogno sia un metodo di utilità per convertire il valore enum nella rappresentazione di stringa pertinente - è sufficiente creare un metodo per questo.

MODIFICA: quando si utilizza un enum per accendere i casi, ma sono necessarie ulteriori informazioni per valore enumerato, tendo a rilasciare l'enumerazione e creare una serie di riferimenti statici e utilizzarli invece nell'assegno. Questo riferimento può essere una classe che include un valore enum, che potrebbe quindi esporre titoli o descrizioni utili.

+0

Le enumerazioni non possono ereditare da nulla. Tutti ereditano da System.Enum. In ogni caso, nell'esempio sopra riportato l'OP sta basando il suo enum sul default di int. Il problema è che sta cercando di assegnare dinamicamente il valore dell'enum. –

+0

Continuerò a lasciare la domanda aperta per ora, ho avuto il tuo suggerimento, ma potrebbe essere possibile che ci sia una soluzione più pulita, grazie Adam. –

+0

Scusa, suppongo che non possano ereditare. Ma possono specificare un tipo: public enum MyShorts: breve {} –

1

È possibile ottenere una risorsa tramite una stringa e poiché è possibile convertire un enum in una stringa, questo è piuttosto semplice.

enum Whatever { Ready, Set, Go } 

public static string GetEnumerationString(Enum enumeration) 
{ 
    string resourceName = 
     string.Concat(enumeration.GetType().Name, "_", enumeration); 
    return ResourceManager.GetString(resourceName); 
} 

Ora in questa implementazione abbiamo il prefisso di tutte le risorse enum con il nome dell'enumerazione. In un progetto l'abbiamo fatto previene le collisioni con altre risorse e le rende facili da trovare. Dovresti quindi assicurarti di aggiungere risorse chiamate Whatever_Ready, Whatever_Set e Whatever_Go.

Allo stesso modo, se si dovesse guardare il codice generato per le stringhe membro statiche come originariamente scritto si sarebbe probabilmente vedere:

public static string DownloadStatus_Complete 
{ 
    return ResourceManager.GetString("DownloadStatus_Complete", Resource.Culture); 
} 
0

IMO, il valore Enum dovrebbe riflettersi al dominio e dovrebbe non specifico per l'interfaccia utente (contesto linguistico).

Si consiglia di fare come questo

public enum DownloadStatus 
{ 
    Complete = 1, 
    Failed = 2, 
    InProgress = 3 
} 

e l'utilizzo di un metodo EnumHelper per ottenere la cultura descrizione specifica nel livello di interfaccia utente

var downloadStatusString = EnumHelper.GetDescription<DownloadStatus>(DownloadStatus.Complete); 

e EnumHelper classe leggerà la stringa specifica cultura dal File di risorse

public static class EnumHelper 
{ 
    public static string GetDescription<T>(T value) 
     where T : struct 
    { 
     if (!typeof(T).IsEnum) 
     { 
      throw new ArgumentException("value must be Enum.", "value"); 
     } 

     var name = value.ToString(); 

     string resourceKey = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", typeof(T).FullName, name); 

     object resource = HttpContext.GetGlobalResourceObject("EnumDescriptions", resourceKey, Thread.CurrentThread.CurrentUICulture); 
     string description = resource as string ?? name; 
     return description; 
    } 
} 

Nota: il nome del file di risorse è EnumDescriptions e la chiave deve essere questa conversione YourNamespace.EnumType_EnumValueInString. (Sto usando HttpContext per ottenere il valore della risorsa e potresti cambiarlo se non stai usando ASP.Net)

+0

il tuo uso di generici è forse eccessivo e non è necessario. Tutte le enumerazioni sono di tipo "Enum". Non vuoi chiamare string.Format solo per concatenare 2 stringhe. –