2009-08-14 13 views
8

Mi chiedevo se il tipo di struttura enum ha un limite ai suoi membri. Ho questa lista molto grande di "variabili" che ho bisogno di memorizzare all'interno di un enum o come costanti in una classe, ma alla fine ho deciso di memorizzarle in una classe, tuttavia, sono un po 'curioso del limite dei membri di un enum (se c'è).Le enumerazioni hanno un limite di membri in C#?

Quindi, le enumerazioni hanno un limite su .Net?

+0

Sono solo curioso di sapere cosa stai facendo che avrebbe bisogno di così tante costanti per dover fare questa domanda ... – NotDan

+0

Beh, certo che non userò il limite di dimensione 2^32, ma ho bisogno di un sacco di "storage" . Stiamo sviluppando un'applicazione correlata all'assicurazione, quindi ci sono un sacco di variabili che devono essere presenti per poter ottenere il punteggio per ottenere un premio e come potete immaginare sono molto (probabilmente 600 a 1.000) –

risposta

16

Sì. Il numero di membri con valori distinti è limitato dal tipo sottostante di enum - per impostazione predefinita questo è Int32, quindi è possibile ottenere molti membri diversi (2^32: trovo difficile raggiungere tale limite), ma è possibile specificare esplicitamente il tipo di fondo in questo modo:

enum Foo : byte { /* can have at most 256 members with distinct values */ } 

Naturalmente, si può avere il maggior numero di membri che vuoi se tutti hanno lo stesso valore:

enum { A, B = A, C = A, ... } 

In entrambi i casi, non v'è probabilmente un limite definito dall'implementazione nel compilatore C#, ma vorrei es pect essere MIN (range-of-Int32, free-memory), piuttosto che un limite rigido.

+0

Grazie, non sapevo che si potesse dichiarare il tipo sottostante di un enum. –

7

A causa di un limite nel formato di file PE, probabilmente non è possibile superare i 100.000.000 di valori. Forse di più, forse meno, ma sicuramente non è un problema.

+0

A molto buon punto. –

6

Dal C# Language Specification 3.0, 1.10:

di un tipo enum formato di memorizzazione e intervallo di possibili valori sono determinati dalla sua tipo sottostante.

Mentre io non sono sicuro al 100% mi aspetterei Microsoft C# compilatore consentendo solo valori enum non negativi, per cui se il tipo di fondo è un Int32 (è, per impostazione predefinita) allora mi aspetterei circa 2^31 valori possibili, ma questo è un dettaglio di implementazione in quanto non è specificato. Se hai bisogno di qualcosa di più, probabilmente stai facendo qualcosa di sbagliato.

+1

I numeri negativi sono consentiti purché non si specifichi esplicitamente un tipo sottostante non firmato: Invalid = -1, None = 0, OptionA = 1, ... –

1

In teoria è possibile utilizzare int64 come tipo di base nell'enumerazione e ottenere 2^63 voci possibili. Altri ti hanno dato risposte eccellenti su questo.

Penso che ci sia una seconda domanda implicita di se si utilizza un enum per qualcosa con un numero enorme di elementi. Questo in realtà si applica direttamente al tuo progetto in molti modi.

Una delle maggiori considerazioni sarebbe la manutenibilità a lungo termine. Pensi che la compagnia cambierà mai la lista dei valori che stai usando? In tal caso, sarà necessario essere retrocompatibili con le liste precedenti? Quanto può essere significativo questo problema? In generale, più grande è il numero di membri in un enum correlato a una probabilità più alta che l'elenco dovrà essere modificato in una data futura.

Le enumerazioni sono ottime per molte cose. Sono puliti, veloci e semplici da implementare. Funzionano perfettamente con IntelliSense e semplificano il lavoro del programmatore successivo, soprattutto se i nomi sono chiari, concisi e se necessario ben documentati.

Il problema è un'enumerazione che presenta anche degli svantaggi. Possono essere problematici se hanno bisogno di essere modificati, specialmente se le classi che li utilizzano vengono mantenute in memoria.

Nella maggior parte dei casi le enumerazioni vengono conservate come valori sottostanti, non come i loro nomi descrittivi.

enum InsuranceClass 
    { 
    Home,  //value = 0 (int32) 
    Vehicle, //value = 1 (int32) 
    Life,  //value = 2 (int32) 
    Health //value = 3 (int32) 
    } 

In questo esempio il valore InsuranceClass.Life otterrebbe persistito come numero 2.

Se un altro programmatore fa una piccola modifica al sistema e aggiunge Pet al enum come questo;

enum InsuranceClass 
    { 
    Home,  //value = 0 (int32) 
    Vehicle, //value = 1 (int32) 
    Pet,  //value = 2 (int32) 
    Life,  //value = 3 (int32) 
    Health //value = 4 (int32) 
    } 

Tutti i dati che escono dal stoccaggio sarà ora mostrare la Vita politiche come Pet politiche. Questo è un errore estremamente facile da fare e può introdurre bug difficili da rintracciare.

Il secondo problema principale con l'enumerazione è che ogni modifica dei dati richiederà la ricostruzione e la ridistribuzione del programma. Questo può causare diversi gradi di dolore. Su un server web che potrebbe non essere un grosso problema, ma se si tratta di un'app utilizzata su 5000 sistemi desktop, si ha un costo completamente diverso per ridistribuire la modifica dell'elenco secondario.

Se è probabile che l'elenco cambi periodicamente, è consigliabile prendere in considerazione un sistema che memorizza tale elenco in qualche altra forma, molto probabilmente al di fuori del codice. I database sono stati progettati appositamente per questo scenario o potrebbe essere utilizzato anche un semplice file di configurazione (non la soluzione preffered). Una pianificazione intelligente delle modifiche può ridurre o evitare i problemi associati alla ricostruzione e alla ridistribuzione del software.

Questo non è un suggerimento per ottimizzare prematuramente il sistema per la possibilità di cambiamento, ma più un suggerimento per strutturare il codice in modo che un probabile cambiamento in futuro non crei un problema grave. Situazioni diverse richiedono decisioni divergenti.

Ecco le mie rozze regole empiriche per l'uso di enumerazioni;

  1. Utilizzarli per classificare e definire altri dati, ma non come dati . Per essere più chiaro, utilizzare InsuranceClass.Life su per determinare come devono essere utilizzati gli altri dati di una classe, ma non aggiungerei al valore sottostante di {pseudocode} InsuranceClass.Life = $653.00 e utilizzando il valore stesso nei calcoli. Le enumerazioni non sono costanti. Fare crea confusione.
  2. Utilizzare le enumerazioni quando è improbabile che l'elenco enum cambi. Le enumerazioni sono fantastiche per concetti fondamentali ma scarse per idee in continua evoluzione. Quando si crea un'enumerazione, questo è un contratto con i futuri programmatori che si desidera evitare.
  3. Se si deve modificare un enum, quindi avere una regola che ognuno segue che si aggiunge alla fine, non al centro. L'alternativa è che tu sia definire valori specifici per ogni enumerazione e non cambiarli mai. Il punto è che è improbabile sapere come altri utenti stanno usando le proprie enumerazioni di valori di e modificandole può causare sofferenza a chiunque altro utilizzando il proprio codice. Questo è un ordine di grandezza più importante per qualsiasi sistema che persiste i dati.
  4. Il corollario di # 2 e # 3 è di non eliminare mai un membro di un enum. Ci sono specifici cerchi infernali per i programmatori che fanno questo in un codebase usato da altri.

Speriamo di aver ampliato le risposte in modo utile.

Problemi correlati