Подтвердить что ты не робот

Преобразуйте массив 'enum' в массив 'int'

Я пытаюсь преобразовать массив Enum в массив int:

public enum TestEnum
{
Item1,
Item2
}

int[] result = Array.ConvertAll<TestEnum, int>(enumArray, new Converter<TestEnum, int>(Convert.ToInt32));

По какой-то причине Convert.ToInt32 не работает при использовании в Array.ConvertAll, поэтому мне пришлось внести некоторые изменения:

int[] result = Array.ConvertAll<TestEnum, int>(enumArray, new Converter<TestEnum, int>(ConvertTestEnumToInt));

public static int ConvertTestEnumToInt(TestEnum te)
{
return (int)te;
}

Просто из любопытства, есть ли способ работать без дополнительного метода?

Привет

4b9b3361

Ответ 1

Просто с помощью анонимного метода:

int[] result = Array.ConvertAll<TestEnum, int>(
    enumArray, delegate(TestEnum value) {return (int) value;});

или с С# 3.0, lambda:

int[] result = Array.ConvertAll(enumArray, value => (int) value);

Ответ 2

К счастью для нас, С# 3.0 включает в себя операцию Cast:

int[] result = enumArray.Cast<int>().ToArray();

Если вы перестанете использовать массивы и начнете использовать IEnumerable<>, вы даже можете избавиться от вызова ToArray().

Ответ 3

TestEnumArray.Select(x = > (int) x)). ToArray()

Ответ 4

int [] b = Array.ConvertAll((int []) Enum.GetValues ​​(typeof (testEnum)), Convert.ToInt32);

Ответ 5

FYI: проверено на .Net4ClientProfile и VS2010

На самом деле вам даже не нужно использовать LINQ. Вы можете просто бросить его обычным способом, при условии, что вы отбрасываете тип до object.

Наличие:

  enum One { one0, one1, one2, one3 };
  enum Two { two0, two1, two2, two3 };

  One[] vals = new One[] { One.one0, One.one3 };

мы можем играть:

//Two[] aa = (Two[])vals; // impossible
  Two[] aa = (Two[])(object)vals; // possible!

  Two bb = aa[1]; // == Two.two3

Сначала я был действительно удивлен, что вторая строка не бросает InvalidCast. Но это не так.

Глядя на типы, объясняет вещи немного:

  bool check2 = bb.GetType().FullName == "Two";   // well, you'd guess that
  bool check3 = aa.GetType().FullName == "One[]"; // what?!

Серьезно! Массив aa не Two[]. Тип массива был "потерян переменной", когда он был добавлен к object, но оба vals и (object)vals, конечно же, относятся к одному и тому же объекту. Затем, после следующего приведения, он все еще является объектом aa, исходным массивом One[], просто скрытым за новым типом переменной.

Объект/переменная bb имеет тип Two, потому что элемент массива считывается как элемент массива Two[] (наряду с типами переменных). Реальный массив One [] скрывается типом Two[], поэтому индексирование Two[] должно приводить к типу Two.

Кроме того, поскольку фактический тип скрыт, и поскольку типы Enum кажутся легко обработанными, давайте еще раз проверить:

  var numbers = (int[])(object)vals;
  var cc = numbers[0] + 10; // == 10, from one0 value
  var dd = numbers[1] + 10; // == 13, from one3 value

и аналогичным образом:

  bool check4 = numbers.GetType().FullName == "One[]"; // not System.Int32[]

Итак, как вы уже могли догадаться, возможен и другой способ:

  var numbers2 = new int[]{ 0, 2, 99 };
  var enums = (One[])(object)numbers2;
  One ee = enums[0]; // == One.one0
  One ff = enums[1]; // == One.one2
  One gg = enums[2]; // == ((One)99)

а int [] также запоминает свой реальный тип, даже если его отличить от One[]:

  bool check5 = numbers2.GetType().FullName == "System.Int32[]";

Кроме того, вы не можете доверять операторам as и is, когда массив передается как object:

  bool really_true1 = vals is One[];
  bool really_true2 = vals is Two[];
  bool really_true3 = vals is System.LoaderOptimization[];

Это был "гота!". для меня недавно.

На самом деле повторно использует исходный объект массива (вместо дублирования его как с LINQ), и он предоставляет его как другой тип - будь то Two [] или int []. Кажется, это "настоящий бросок", без бокса. Многое отличается от копирования и преобразования с помощью LINQ.