将'enum'数组转换为'int'数组

时间:2009-01-23 09:43:24

标签: c# .net

我正在尝试将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;
}

出于好奇,有没有办法让这个工作没有使用额外的方法?

此致

6 个答案:

答案 0 :(得分:45)

使用匿名方法进行投射:

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

或使用C#3.0,lambda:

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

答案 1 :(得分:43)

幸运的是,C#3.0包含Cast操作:

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

如果您停止使用数组并开始使用IEnumerable<>,您甚至可以摆脱ToArray()来电。

答案 2 :(得分:7)

TestEnumArray.Select(x =&gt;(int)x))。ToArray()

答案 3 :(得分:1)

仅供参考:在.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's value
  var dd = numbers[1] + 10; // == 13, from one3's 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传递时,您无法信任isobject运算符:

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

这个是'骗子'!对我来说最近。

它实际上重用原始数组对象(而不是像LINQ一样重复它)并且它将它暴露为不同的类型 - 无论是Two []还是int []。它似乎是一个“真正的演员”,没有拳击。与LINQ驱动的复制和转换有很大不同。

答案 4 :(得分:1)

scala> val a = Array((1, 1), (3, 3), (2, 2)) a: Array[(Int, Int)] = Array((1,1), (3,3), (2,2)) scala> a.sorted res1: Array[(Int, Int)] = Array((1,1), (2,2), (3,3)) scala> val a = Array((1, 2), (3, 1), (2, 3)) a: Array[(Int, Int)] = Array((1,2), (3,1), (2,3)) scala> a.sorted res2: Array[(Int, Int)] = Array((1,2), (2,3), (3,1)) scala> val a = Array((1, 2), (3, 1), (1, 1)) a: Array[(Int, Int)] = Array((1,2), (3,1), (1,1)) scala> a.sorted res3: Array[(Int, Int)] = Array((1,1), (1,2), (3,1))

答案 5 :(得分:1)

这就像一个魅力:

var intArray = enumArray.Select(e => (int)e).ToArray();

就像这样:

var intList = enumArray.Select(e => (int)e).ToList();