recorrer - matriz en c# consola
Convierta una matriz de ''enum'' a una matriz de ''int'' (5)
Estoy tratando de convertir una matriz Enum a una matriz int:
public enum TestEnum
{
Item1,
Item2
}
int[] result = Array.ConvertAll<TestEnum, int>(enumArray, new Converter<TestEnum, int>(Convert.ToInt32));
Por alguna razón, Convert.ToInt32 no funciona cuando se usa en Array.ConvertAll, así que tuve que hacer algunos cambios:
int[] result = Array.ConvertAll<TestEnum, int>(enumArray, new Converter<TestEnum, int>(ConvertTestEnumToInt));
public static int ConvertTestEnumToInt(TestEnum te)
{
return (int)te;
}
Solo por curiosidad, ¿hay alguna forma de que funcione sin usar un método adicional?
Saludos
Solo echa usando un método anónimo:
int[] result = Array.ConvertAll<TestEnum, int>(
enumArray, delegate(TestEnum value) {return (int) value;});
o con C # 3.0, una lambda:
int[] result = Array.ConvertAll(enumArray, value => (int) value);
Afortunadamente para nosotros, C # 3.0 incluye una operación de Cast
:
int[] result = enumArray.Cast<int>().ToArray();
Si deja de usar matrices y comienza a usar IEnumerable<>
, incluso puede deshacerse de la llamada ToArray()
.
FYI: probado en .Net4ClientProfile y VS2010
En realidad, ni siquiera necesita usar LINQ. Puedes simplemente lanzarlo de forma normal, siempre que sueltes el tipo hacia abajo para object
.
Teniendo:
enum One { one0, one1, one2, one3 };
enum Two { two0, two1, two2, two3 };
One[] vals = new One[] { One.one0, One.one3 };
podemos jugar:
//Two[] aa = (Two[])vals; // impossible
Two[] aa = (Two[])(object)vals; // possible!
Two bb = aa[1]; // == Two.two3
Al principio, realmente me sorprendió que la segunda línea no arroje InvalidCast. Pero no es así
Mirar los tipos explica las cosas un poco:
bool check2 = bb.GetType().FullName == "Two"; // well, you''d guess that
bool check3 = aa.GetType().FullName == "One[]"; // what?!
¡Seriamente! La matriz aa
no es Two[]
. El tipo de matriz se ha "perdido por variable" cuando se emitió a object
, pero vals
y (object)vals
todavía se refieren al mismo objeto. Luego, después del siguiente elenco, sigue siendo el objeto aa
, el conjunto original de One[]
, simplemente escondido detrás de un nuevo tipo de variable.
El objeto / variable bb
tiene el tipo de Two
porque el elemento de la matriz se lee como un elemento de una matriz Two[]
(junto con los tipos de la variable). La matriz real One [] está oculta por el tipo Two[]
, por lo que indexar Two[]
debe dar como resultado un valor de Two
type.
Además, dado que el tipo real está oculto y dado que los tipos Enum parecen tratarse a la ligera, veamos otra cosa:
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
y similarmente
bool check4 = numbers.GetType().FullName == "One[]"; // not System.Int32[]
Entonces, como ya habrás adivinado, al revés también es posible:
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)
y int [] también recuerda su tipo real, incluso si se convierte en One[]
:
bool check5 = numbers2.GetType().FullName == "System.Int32[]";
Aún más, no puede confiar en los operadores as
y is
cuando la matriz se pasa como un object
:
bool really_true1 = vals is One[];
bool really_true2 = vals is Two[];
bool really_true3 = vals is System.LoaderOptimization[];
¡Este era un ''gotha!'' para mi recientemente
En realidad, reutiliza el objeto de matriz original (en lugar de duplicarlo como con LINQ) y lo expone como un tipo diferente, ya sea Two [] o int []. Parece ser un "elenco verdadero", no hay boxeo. Mucho diferente a la copia y conversión impulsada por LINQ.
TestEnumArray.Select (x => (int) x)). ToArray ()
int [] b = Array.ConvertAll ((int []) Enum.GetValues (typeof (testEnum)), Convert.ToInt32);