Почему отрицательные члены перечисления перечислены последним foreach?

В С#, если мы определяем enum, который содержит член, соответствующий отрицательному значению, а затем мы перебираем значения enum, отрицательное значение не наступает первым, а последнее. Почему это происходит? На других языках (C, С++, Ada и т.д.) Повторение с помощью enum даст вам порядок, в котором вы его определили.

MSDN имеет хороший пример этого поведения:

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

Ответ 1

Из самой страницы документации, на которую вы ссылаетесь,, мой акцент:

Элементы массива сортируются по двоичным значениям констант перечисления (т.е. по величине без знака).

Копаясь в коде CLR (2.0 SSCLI) и получая намного более низкий уровень, чем мне действительно комфортно, похоже, что в конечном счете это происходит потому, что внутренние значения enum хранятся в том, что выглядит так (обратите внимание, что это С++ ):

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;

Как можно видеть, это неподписанные типы, которые содержат фактические значения - поэтому, когда эти значения испускаются для перечисления, естественно, они находятся в неподписанном порядке.