2016-01-31 14 views
7

C# .NET 4.5, Windows 10, ho il seguente enum:C# Enum.TryParse analizza stringhe numero non valido

private enum Enums 
{ 
    A=1, B=2, C=3 
} 

E questo programma si comporta in un modo molto strano:

public static void Main() 
{ 
    Enums e; 
    if (Enum.TryParse("12", out e)) 
    { 
     Console.WriteLine("Parsed {0}", e); 
    } 
    else 
    { 
     Console.Write("Not parsed"); 
    } 
    Console.ReadLine(); 
} 

I si aspetterebbe che il risultato del metodo TryParse sia falso, ma con mia sorpresa la console mostra "Parsed 12". Nella finestra di controllo mostra anche che il valore è "12" ed è del tipo Enums!

Questo vale per qualsiasi stringa di numeri che ho provato (ad esempio "540"), ma non per stringhe che includono lettere ("A12", "12A").

Posso facilmente superarlo verificando prima se si tratta di una stringa numero-solo, ma perché questo è il comportamento? È di progettazione?

Grazie! Ido

+1

Sì, è di progettazione. È una buona idea che se '.ToString()' su un valore può restituire una stringa specifica, e il tipo in questione ha un metodo '.Parse()', allora il metodo di analisi dovrebbe accettare quella stringa in cambio. Poiché le enum possono contenere valori "sconosciuti" (cioè valori che non hanno un nome nell'enumerazione) e '.ToString()' restituiranno questi come il numero in una stringa, quindi seguirà '.Parse() 'dovrebbe accettare una stringa che contiene solo un numero intero. Quindi sì, questo è di design. Potresti non essere d'accordo con questa decisione, ma è quello che è. –

risposta

6

Internamente, enumerazioni vengono memorizzate come numeri interi in modo che è probabilmente il motivo TryParse sta tornando vero per gli interi vengono passati.

Per quanto riguarda il motivo per cui ogni intero sta lavorando, è in base alla progettazione. Da MSDN (enfasi mia):

Quando termina, questo metodo risultato contiene un oggetto di tipo Tenum cui valore è rappresentato dal valore se l'operazione di analisi ha esito positivo. Se l'operazione di analisi non riesce, il risultato contiene il valore predefinito del tipo sottostante di TEnum . Si noti che questo valore non deve essere un membro di l'enumerazione TEnum. Questo parametro è passato non inizializzato.

+3

Grazie! Non stavo cercando nel posto giusto .. Inoltre, apparentemente dal MSDN: Se questo comportamento non è desiderabile, chiamare il metodo IsDefined per garantire che una particolare rappresentazione di stringa di un intero sia effettivamente un membro di TEnum. –

+0

Prego. Sì, usare 'IsDefined' sarebbe d'aiuto se ci fosse la possibilità che un intero non membro possa essere passato.È possibile creare un metodo di estensione che gestisca il controllo 'IsDefined' dopo l'analisi in modo da poter utilizzare tale metodo invece del' TryParse' predefinito. – keyboardP

2

Una variabile o un campo di tipo di enumerazione può contenere qualsiasi valore di questo tipo di fondo, così memorizzare il valore di 12 in una variabile di tipo Enums nel suo caso è del tutto legale:

var e = (Enums) 12; 
var i = (int) e; // i is 12 

Pertanto , Enum.TryParse deve essere in grado di analizzare qualsiasi valore di tipo int (o qualsiasi tipo intero sottostante utilizzato nella propria enumerazione).

Se si desidera rifiutare valori senza alcuna rappresentazione nell'enumerazione, controllarli con Enum.IsDefined.

Problemi correlati