С# перечисление длинных значений

Мне было интересно, почему это выражение:

public enum ECountry : long
{
    None,
    Canada,
    UnitedStates
}

требуется ли для любого из своих значений?

long ID = ECountry.Canada;
// Error Cannot implicitly convert type 'ECountry' to 'long'.
// An explicit conversion exists (are you missing a cast?)

И есть ли способ получить длинную ценность непосредственно из перечисления, помимо кастинга?

Это не работает, например:

public enum ECountry : long
{
    None = 0L,
    Canada = 1L,
    UnitedStates=2L
}

Ответ 1

Проблема заключается не в том, что базовый тип по-прежнему является int. Это long, и вы можете назначить long значения членам. Однако вы никогда не можете просто присвоить значение enum целому типу без трансляции. Это должно работать:

public enum ECountry : long
{
    None,
    Canada,
    UnitedStates = (long)int.MaxValue + 1;
}

// val will be equal to the *long* value int.MaxValue + 1
long val = (long)ECountry.UnitedStates;

Ответ 2

Основной тип enum умолчанию - int. enum может быть любой целочисленный тип, кроме char.

Если вы хотите, чтобы это было long, вы можете сделать что-то вроде этого:

// Using long enumerators
using System;
public class EnumTest 
{
    enum Range :long {Max = 2147483648L, Min = 255L};
    static void Main() 
    {
        long x = (long)Range.Max;
        long y = (long)Range.Min;
        Console.WriteLine("Max = {0}", x);
        Console.WriteLine("Min = {0}", y);
    }
}

Здесь важна актерская роль. И, как говорит @dlev, цель использования long в enum - поддерживать большое количество флагов (более 32, поскольку 2 ^ 32 - 4294967296, а long может содержать более 2 ^ 32).

Ответ 3

Вы должны указать перечисление, чтобы получить от него значение, или оно останется типом enum

Ответ 4

Из msdn: http://msdn.microsoft.com/en-us/library/sbbt4032%28v=vs.80%29.aspx

В этом примере параметр базового типа используется для объявления перечисления, члены которого имеют тип long. Обратите внимание, что, хотя базовый тип перечисления длинный, члены перечисления все равно должны быть явно преобразованы в тип long, используя листинг.

// keyword_enum2.cs
// Using long enumerators
using System;
public class EnumTest 
{
    enum Range :long {Max = 2147483648L, Min = 255L};
    static void Main() 
    {
        long x = (long)Range.Max;
        long y = (long)Range.Min;
        Console.WriteLine("Max = {0}", x);
        Console.WriteLine("Min = {0}", y);
    }
}

Вывод

Макс = 2147483648 Мин = 255

Ответ 5

AFAIK вам нужно бросить.

В статье MSDN говорится: "Однако для преобразования из типа enum в интегральный тип требуется явное преобразование" (либо int, либо long)

Вы можете проверить это: http://msdn.microsoft.com/en-us/library/sbbt4032%28v=vs.80%29.aspx