Почему в C# такой неудобный enum?

177
22 октября 2018, 19:10

Есть ли возможность использовать шарповый энум как в плюсах? Вот что я имею ввиду:

enum exampleEnum
{
    CELL1,
    CELL2,
    CELL3
}
void Foo ()
{
    int exampleArray [3] = { 0, 0, 0 };
    exampleArray[CELL1] = 23;
    ...
    exampleArray[CELL3] = 88;
    ...
}

Не понимаю как без крестового энума жить.

Answer 1

Как привести enum к int уже написали. Предложу альтернативу.

Использовать перечисление как ключ может быть удобнее через Dictionary:

var dict = new Dictionary<ExampleEnum, int>();
dict[ExampleEnum.CELL1] = 23;
...
dict[ExampleEnum.CELL3] = 88;
...
//вывод словаря с проверкой существования
foreach(ExampleEnum cell in Enum.GetValues(typeof(ExampleEnum))) {
    Console.WriteLine(dict.ContainsKey(cell) ? dict[cell] : 0);
}

Словарь будет работать медленнее массива, но, учитывая крайне малое количество ключей, разница видится несущественной.

Бонус: этот код не понадобится править если в перечислении изменится порядок или добавятся новые значения.

Бонус2: словарь проверяет что ключ ExampleEnum, а не случайный int что позволит избежать ошибок:

exampleArray[1]++; //что это?
exampleArray[OtherEnum.NOT_CELL] = 15; //почему?
Answer 2

Как-то так

void Foo ()
{
    int[] exampleArray = { 0, 0, 0 };
    exampleArray[Convert.ToInt32(exampleEnum.CELL1)] = 23;
    ...
    exampleArray[Convert.ToInt32(exampleEnum.CELL3)] = 88;
    ...
}

C# лишён черт слабой типизации к которым вы привыкли в С++. Поэтому это и есть нормальный способ, приведения значения перечисления к Int32. Если вы желаете избежать конвертации, а значит хотите использовать значение перечисление как индекс коллекции, то вы можете реализовать свою коллекцию.

class ExampleEnumCollection<T> 
{
    private readonly T[] _inner;
    public T this[exampleEnum index]
    {
        get { return _inner[(int)index]; }
        set { _inner[(int)index] = value; }
    }        
    public ExampleEnumCollection(int count, T defaultValue)
    {
        _inner = new T[count];
        for (int i = 0; i < count; i++)
        {
            _inner[i] = defaultValue;
        }            
    }
}
void Foo2()
{
    var exampleCollection = new ExampleEnumCollection<int>(3, 0);
    exampleCollection[exampleEnum.CELL1] = 23;
    exampleCollection[exampleEnum.CELL3] = 88;
}
READ ALSO
Opencart кастомное поле в админке

Opencart кастомное поле в админке

добавил допполе "описание внизу" в категорию в админке

173
Инициализация массива в PHP

Инициализация массива в PHP

Недавно столкнулся с задачей, что нужно массив, состоящий из n элементов инициализировать нулямиСделал примерно так:

157
Не выводит все записи из ACF Wordpress

Не выводит все записи из ACF Wordpress

На странице нужно сделать добавление карточек, сделал через ACF путем регистрации нового поста:

177