Pregunta breve: ¿Cómo puedo modificar elementos individuales en un List
? (O más precisamente, los miembros de un struct
almacenan en un List
?)C# modificando las estructuras en una lista <T>
explicación completa:
primer lugar, los struct
definiciones utilizadas a continuación:
public struct itemInfo
{
...(Strings, Chars, boring)...
public String nameStr;
...(you get the idea, nothing fancy)...
public String subNum; //BTW this is the element I'm trying to sort on
}
public struct slotInfo
{
public Char catID;
public String sortName;
public Bitmap mainIcon;
public IList<itemInfo> subItems;
}
public struct catInfo
{
public Char catID;
public String catDesc;
public IList<slotInfo> items;
public int numItems;
}
catInfo[] gAllCats = new catInfo[31];
gAllCats
se rellena en la carga, y así sucesivamente en la línea mientras el programa se ejecuta.
El problema surge cuando quiero ordenar los objetos itemInfo
en la matriz subItems
. Estoy usando LINQ para hacer esto (porque no parece haber otra forma razonable de ordenar listas de tipo no incorporado). Así que aquí es lo que tengo:
foreach (slotInfo sInf in gAllCats[c].items)
{
var sortedSubItems =
from itemInfo iInf in sInf.subItems
orderby iInf.subNum ascending
select iInf;
IList<itemInfo> sortedSubTemp = new List<itemInfo();
foreach (itemInfo iInf in sortedSubItems)
{
sortedSubTemp.Add(iInf);
}
sInf.subItems.Clear();
sInf.subItems = sortedSubTemp; // ERROR: see below
}
El error es: "No se puede modificar miembros de 'SINF' porque es una 'variable de iteración foreach'".
a, esta restricción no tiene sentido; ¿no es ese un uso principal de la construcción foreach?
b, (también por despecho) ¿Qué hace Clear() si no modifica la lista? (Por cierto, la lista se borra, de acuerdo con el depurador, si elimino la última línea y la ejecuto)
Así que traté de adoptar un enfoque diferente, y ver si funcionaba con un ciclo for normal. (Al parecer, esto sólo es permisible porque gAllCats[c].items
es en realidad un IList
; no creo que le permita indexar un habitual List
esta manera.)
for (int s = 0; s < gAllCats[c].items.Count; s++)
{
var sortedSubItems =
from itemInfo iInf in gAllCats[c].items[s].subItems
orderby iInf.subNum ascending
select iInf;
IList<itemInfo> sortedSubTemp = new List<itemInfo>();
foreach (itemInfo iInf in sortedSubItems)
{
sortedSubTemp.Add(iInf);
}
//NOTE: the following two lines were incorrect in the original post
gAllCats[c].items[s].subItems.Clear();
gAllCats[c].items[s].subItems = sortedSubTemp; // ERROR: see below
}
Esta vez, el error es: "No se puede modificar el devuelve el valor de 'System.Collections.Generic.IList.this [int]' porque no es una variable. " ¡Uf! ¿Qué es, si no es una variable? y cuando se convirtió en un "valor de retorno"?
Sé que tiene que haber una forma "correcta" de hacerlo; Estoy llegando a esto desde el fondo C y sé que podría hacerlo en C (aunque con un buen manejo de la memoria manual)
He buscado y parece que ArrayList
ha pasado de moda en a favor de los tipos genéricos (estoy usando 3.0) y no puedo usar una matriz ya que el tamaño debe ser dinámico.
Impresionante, eso funciona. ¡Muchas gracias! – andersop
gracias por señalar esto. Sabía sobre esto en cuanto a la modificación de la propiedad de una estructura, pero no sabía que se aplicaba a las colecciones genéricas. Simplemente asumí que la Lista en sí era una clase, por lo que el indexador devolvería una referencia A la estructura. Imagino que así es como funciona con colecciones no genéricas. gracias de nuevo – LoveMeSomeCode
Acabo de encontrar esta solución. Funciona - gracias! –