2013-08-09 3 views
10

In C#, wenn wir eine enum definieren, die ein Mitglied enthält, das einem negativen Wert entspricht, und dann über die Werte von enum iterieren, kommt der negative Wert nicht an erster Stelle, sondern an letzter Stelle. Warum passiert das? In anderen Sprachen (C, C++, Ada usw.) erhalten Sie bei einer Iteration über enum die Reihenfolge, in der Sie sie definiert haben.Warum werden negative enum-Mitglieder zuletzt von foreach aufgelistet?

MSDN hat eine gute example of this behavior:

using System; 

enum SignMagnitude { Negative = -1, Zero = 0, Positive = 1 }; 

public class Example 
{ 
    public static void Main() 
    { 
     foreach (var value in Enum.GetValues(typeof(SignMagnitude))) 
     { 
      Console.WriteLine("{0,3}  0x{0:X8}  {1}", 
           (int) value, ((SignMagnitude) value)); 
     } 
    } 
} 

// The example displays the following output: 
//   0  0x00000000  Zero 
//   1  0x00000001  Positive 
//  -1  0xFFFFFFFF  Negative 
+2

Es wird wahrscheinlich als unsigned sortiert. – SLaks

+4

Sie haben es gemacht [* einen * Schritt weiter als viele Programmierer] (http://stackoverflow.com/questions/18095665/a-lambda-expression-with-a-statement-body-cannot-be-converted-to-an -expression-t/18095816 # comment26488750_18095816) mit der Dokumentation. Beim nächsten Mal lese es: "Die Elemente des Arrays sind nach den binären Werten der Aufzählungskonstanten sortiert (**, dh durch ihre vorzeichenlose Größe **)." – jason

+0

Aus demselben [MSDN] (http://msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx) Artikel: "Die Elemente des Arrays sind nach den binären Werten der Aufzählungskonstanten sortiert (Das heißt, durch ihre vorzeichenlose Größe). " – natenho

Antwort

15

Von the very documentation page you link to, mein Schwerpunkt:

Die Elemente des Arrays durch die binären Werte der Enumerationskonstanten sortiert werden (das heißt, durch ihre unsigned Größe).

Graben in den CLR-Code (die 2,0 SSCLI) und weit niedrigere Ebene bekommen, als ich mit wirklich bequem bin, sieht es aus wie letztlich ist dies, weil intern Enum-Wert in etwas gespeichert werden, die wie folgt aussehen (Anmerkung dies ist C++):

class EnumEEClass : public EEClass 
{ 
    friend class EEClass; 

private: 

    DWORD   m_countPlusOne; // biased by 1 so zero can be used as uninit flag 
    union 
    { 
     void  *m_values; 
     BYTE  *m_byteValues; 
     USHORT  *m_shortValues; 
     UINT  *m_intValues; 
     UINT64  *m_longValues; 
    }; 
    LPCUTF8   *m_names; 

Wie man sehen kann, ist es unsigned Typen ist, dass die tatsächlichen Werte zu halten - so, wenn diese Werte für die Zählung emittiert werden, natürlich sie in ihrem unsigned Ordnung sind.

+8

Interessanterweise begann dies als ein Fehler (http://connect.microsoft.com/VisualStudio/feedback/details/98147/enum-getvalues). Wenn Sie frühere Versionen der Dokumentation vor 3.5 betrachten, gibt es keine offizielle Erwähnung, dass sie ihre vorzeichenlose Größe verwendet haben. Aufgrund der Unfähigkeit, es zu beheben, ohne bestehende Anwendungen zu brechen, schätze ich, dass sie gerade die Dokumente aktualisiert haben: D – keyboardP

+1

Danke @keyboardP, das ist, was ich wirklich gefragt habe. – gmletzkojr

+1

Gute Antwort. Es setzt jedoch voraus, dass der Leser weiß, wie negative Zahlen dargestellt werden (faktisch [Zweierkomplement] (http://en.wikipedia.org/wiki/Signed_number_representation), obwohl die [C# -Spezifikation] (http: //www.ecma- international.org/publications/standards/Ecma-334.htm) erfordert diese Methode nicht explizit für die Darstellung vorzeichenbehafteter Ganzzahlen).Dieses Wissen ist notwendig, um zu verstehen, warum sie als unsigned behandelt werden, wenn sie nach positiven Zahlen folgen. – stakx

Verwandte Themen