2013-08-09 10 views
10

W języku C#, jeśli zdefiniujemy enum, który zawiera element odpowiadający wartości ujemnej, a następnie sprawdzamy wartości enum, wartość ujemna nie jest pierwsza, ale ostatnia. Dlaczego tak się dzieje? W innych językach (C, C++, Ada, itp.), Iterowanie po numerze enum da ci kolejność, w której je zdefiniowałeś.Dlaczego wykluczeni członkowie wyliczeni są na końcu przez foreach?

MSDN ma dobry 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

Prawdopodobnie został posortowany jako niepodpisany. – SLaks

+4

Udało ci się [* jeden * krok dalej niż wielu programistów] (http://stackoverflow.com/questions/18095665/a-lambda-expression-with-a-ssetement-body-cannot-be-converted-to-an -expression-t/18095816 # comment26488750_18095816) poprzez wprowadzenie do dokumentacji. Następnym razem przeczytaj: "Elementy tablicy są posortowane według binarnych wartości stałych wyliczeniowych (**, czyli z ich niepodpisaną wielkością **)." – jason

+0

Z tego samego artykułu [MSDN] (http://msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx): "Elementy tablicy są posortowane według binarnych wartości stałych wyliczeniowych (czyli przez ich niepodpisaną wielkość). " – natenho

Odpowiedz

15

Od the very documentation page you link to, mój nacisk:

elementy tablicy są klasyfikowane według wartości binarnych stałych wyliczeniowych (czyli przez swoich unsigned magnitude).

Kopanie do kodu CLR (The SSCLI 2,0) i uzyskanie znacznie niższego poziomu niż jestem naprawdę komfortowo, wygląda na to, bo w końcu jest to wewnętrznie enum wartości są przechowywane w coś, co wygląda tak (uwaga to jest 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; 

Jak widać, jest to niepodpisane typy, które posiadają wartości rzeczywiste - tak, gdy wartości te są emitowane do policzenia, oczywiście są one w ich unsigned kolejności.

+8

Co ciekawe, zaczęło się to od błędu (http://connect.microsoft.com/VisualStudio/feedback/details/98147/enum-getvalues). Jeśli przyjrzysz się wcześniejszym wersjom dokumentacji przed 3.5, nie ma oficjalnej wzmianki o tym, że używał on swojej niepodpisanej wielkości. Z powodu niemożności naprawienia go bez przerywania istniejących aplikacji, wydaje mi się, że właśnie zaktualizowali dokumenty: D – keyboardP

+1

Dzięki @keyboardP, o to naprawdę pytałem. – gmletzkojr

+1

Dobra odpowiedź. Zakłada jednak, że czytelnik wie, w jaki sposób reprezentowane są liczby ujemne (w rzeczywistości [uzupełnienie dwójki] (http://en.wikipedia.org/wiki/Zaprojektowany_numer_reprezentacji), chociaż specyfikacja [C# spec] (http: //www.ecma- international.org/publications/standards/Ecma-334.htm) nie wymaga jawnie tej metody do reprezentowania liczb całkowitych ze znakiem).Ta wiedza jest niezbędna, aby zrozumieć, dlaczego traktowanie ich jako niepodpisanych powoduje, że podążają za liczbami dodatnimi. – stakx

Powiązane problemy