Krótkie pytanie: Jak zmodyfikować poszczególne elementy w List
? (Lub bardziej precyzyjnie, członkowie struct
przechowywane w List
?)C# modyfikowanie struktur na liście <T>
Pełne wyjaśnienie:
pierwsze, definicje struct
stosowane poniżej:
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
jest wypełniana na obciążenia, i tak dalej wzdłuż linii, gdy program jest uruchomiony.
Problem pojawia się, gdy chcę posortować obiekty itemInfo
w tablicy subItems
. Używam LINQ, aby to zrobić (ponieważ nie istnieje żaden inny rozsądny sposób sortowania list typu nie-wbudowanego). Więc oto co mam:
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
}
Błąd jest, „Nie można modyfikować członków«sInf», ponieważ jest to«foreach iteracji zmienna»”.
a, to ograniczenie nie ma sensu; czy nie jest to podstawowym zastosowaniem konstruktu foreach?
b, (również na przekór), co robi Clear(), jeśli nie modyfikować listy? (BTW, lista zostanie oczyszczona, zgodnie z debuggerem, jeśli usunę ostatnią linię i uruchomię ją.)
Próbowałem więc zastosować inne podejście i sprawdzić, czy zadziałało, używając zwykłej pętli for. (Wydaje się, że to jest tylko dopuszczalna, ponieważ gAllCats[c].items
jest rzeczywiście IList
; nie sądzę, pozwoli to na indeksie regularny List
ten sposób.)
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
}
Tym razem jest błąd: „Nie można modyfikować zwracana wartość "System.Collections.Generic.IList.this [int]", ponieważ nie jest zmienną. " Ugh! Co to jest, jeśli nie zmienna? i kiedy stała się "wartością zwrotną"?
Wiem, że musi istnieć "poprawny" sposób, aby to zrobić; Przychodzę do tego z tła C i wiem, że mogłem to zrobić w C (aczkolwiek z dużym ręcznym zarządzaniem pamięcią).
Przeszukałem i wydaje mi się, że ArrayList
wyszedł z mody w faworyzowanie typów ogólnych (używam wersji 3.0) i nie mogę używać tablicy, ponieważ rozmiar musi być dynamiczny.
Niesamowite, to działa. Wielkie dzięki! – andersop
dzięki za wskazanie tego. Wiedziałem o tym, jeśli chodzi o modyfikowanie właściwości właściwości struct, ale nie wiedziałem, że ma ona zastosowanie do kolekcji ogólnych. Po prostu założyłem, że sama lista była klasą, więc indeksator zwróci referencję do struktury. Wyobrażam sobie, że tak to działa z nietypowymi kolekcjami. Jeszcze raz dziękuję – LoveMeSomeCode
Właśnie znalazłem to rozwiązanie. Działa - dzięki! –