我正在尝试将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;
}
出于好奇,有没有办法让这个工作没有使用额外的方法?
此致
答案 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
传递时,您无法信任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驱动的复制和转换有很大不同。
答案 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();