Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A .NET-futtatókörnyezet számos gyűjteménytípust biztosít, amelyek a kapcsolódó objektumok csoportjait tárolják és kezelik. A gyűjtemények egyes típusait, például System.Arraya , System.Span<T>és System.Memory<T>a C# nyelvet is felismeri a rendszer. Emellett a gyűjtemény elemeinek számbavételéhez az olyan felületek is felismerhetőek, mint System.Collections.Generic.IEnumerable<T> a nyelv.
A gyűjtemények rugalmas módot biztosítanak az objektumcsoportok használatához. A különböző gyűjteményeket az alábbi jellemzők szerint sorolhatja be:
- Elemhozzáférés: Minden gyűjtemény számba vehető az egyes elemek sorrendben való eléréséhez. Egyes gyűjtemények index alapján férnek hozzá az elemekhez, az elem pozíciója egy rendezett gyűjteményben. A leggyakoribb példa a .System.Collections.Generic.List<T> Más gyűjtemények kulcsonként férnek hozzá az elemekhez, ahol egy érték egyetlen kulccsal van társítva. A leggyakoribb példa a .System.Collections.Generic.Dictionary<TKey,TValue> Ezek közül a gyűjteménytípusok közül választhat az alkalmazás elemeinek elérésének módjától függően.
- Teljesítményprofil: Minden gyűjtemény különböző teljesítményprofilokkal rendelkezik olyan műveletekhez, mint például elem hozzáadása, elem keresése vagy elem eltávolítása. Az alkalmazásban leggyakrabban használt műveletek alapján választhat gyűjteménytípust.
- Dinamikus növekedés és zsugorodás: A legtöbb gyűjtemény támogatja az elemek dinamikus hozzáadását vagy eltávolítását. Nevezetesen, Arrayés System.Span<T>System.Memory<T> nem.
Ezen jellemzők mellett a futtatókörnyezet speciális gyűjteményeket is biztosít, amelyek megakadályozzák az elemek hozzáadását vagy eltávolítását, illetve a gyűjtemény elemeinek módosítását. Más specializált gyűjtemények biztonságot nyújtanak az egyidejű hozzáféréshez többszálú alkalmazásokban.
Az összes gyűjteménytípus megtalálható a .NET API-referenciában. További információ: Gyakori gyűjteménytípusok és gyűjteményosztály kiválasztása.
Feljegyzés
A cikkben szereplő példákhoz előfordulhat, hogy a névterekre és a névterekre vonatkozó irányelveketSystem.Collections.GenericSystem.Linq.
A tömböket a C# nyelv szintaxisa támogatja System.Array . Ez a szintaxis tömörebb deklarációkat biztosít a tömbváltozókhoz.
System.Span<T>
ref struct Olyan típus, amely az elemek másolása nélkül biztosít pillanatképet az elemek sorozatáról. A fordító biztonsági szabályokat kényszerít ki annak érdekében, hogy a Span hivatkozott sorozat után ne lehessen hozzáférni a hatókörhöz. Számos .NET API-ban használják a teljesítmény javítása érdekében.
Memory<T> hasonló viselkedést biztosít, ha nem tud típust ref struct használni.
A C# 12-től kezdődően az összes gyűjteménytípus inicializálható egy Gyűjtemény kifejezéssel.
Indexelhető gyűjtemények
Az indexelhető gyűjtemények olyan gyűjtemények, ahol az egyes elemeket az index használatával érheti el. Az elemek indexe a sorrendben előtte lévő elemek száma. Ezért az index 0 által hivatkozott elem az első elem, az index 1 a második és így tovább. Ezek a példák az osztályt List<T> használják. Ez a leggyakoribb indexelhető gyűjtemény.
Az alábbi példa sztringlistát hoz létre és inicializál, eltávolít egy elemet, és hozzáad egy elemet a lista végéhez. Minden módosítás után egy foreachvégighalad a sztringeken:
// Create a list of strings by using a
// collection initializer.
List<string> salmons = ["chinook", "coho", "pink", "sockeye"];
// Iterate through the list.
foreach (var salmon in salmons)
{
Console.Write(salmon + " ");
}
// Output: chinook coho pink sockeye
// Remove an element from the list by specifying
// the object.
salmons.Remove("coho");
// Iterate using the index:
for (var index = 0; index < salmons.Count; index++)
{
Console.Write(salmons[index] + " ");
}
// Output: chinook pink sockeye
// Add the removed element
salmons.Add("coho");
// Iterate through the list.
foreach (var salmon in salmons)
{
Console.Write(salmon + " ");
}
// Output: chinook pink sockeye coho
Az alábbi példa az elemeket index alapján távolítja el a listából. Utasítás helyett foreach egy csökkenő sorrendben iteráló utasítást for használ. A RemoveAt metódus hatására az eltávolított elemek után az elemek indexértéke alacsonyabb lesz.
List<int> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// Remove odd numbers.
for (var index = numbers.Count - 1; index >= 0; index--)
{
if (numbers[index] % 2 == 1)
{
// Remove the element by specifying
// the zero-based index in the list.
numbers.RemoveAt(index);
}
}
// Iterate through the list.
// A lambda expression is placed in the ForEach method
// of the List(T) object.
numbers.ForEach(
number => Console.Write(number + " "));
// Output: 0 2 4 6 8
A benne lévő List<T>elemek típusához saját osztályt is definiálhat. Az alábbi példában a Galaxy kódban definiáljuk a List<T> használt osztályt.
private static void IterateThroughList()
{
var theGalaxies = new List<Galaxy>
{
new (){ Name="Tadpole", MegaLightYears=400},
new (){ Name="Pinwheel", MegaLightYears=25},
new (){ Name="Milky Way", MegaLightYears=0},
new (){ Name="Andromeda", MegaLightYears=3}
};
foreach (Galaxy theGalaxy in theGalaxies)
{
Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears);
}
// Output:
// Tadpole 400
// Pinwheel 25
// Milky Way 0
// Andromeda 3
}
public class Galaxy
{
public string Name { get; set; }
public int MegaLightYears { get; set; }
}
Az indexekről további információt az Indexek és tartományok felfedezése című cikkben talál.
Kulcs-/értékpár-gyűjtemények
Ezek a példák az osztályt Dictionary<TKey,TValue> használják. Ez a leggyakoribb szótárgyűjtemény. A szótárgyűjtemények lehetővé teszik a gyűjtemény elemeinek elérését az egyes elemek kulcsával. A szótár minden egyes hozzáadása egy értékből és a hozzá tartozó kulcsból áll.
Az alábbi példa létrehoz egy gyűjteményt Dictionary , és egy utasítással foreach végigvezeti a szótáron.
private static void IterateThruDictionary()
{
Dictionary<string, Element> elements = BuildDictionary();
foreach (KeyValuePair<string, Element> kvp in elements)
{
Element theElement = kvp.Value;
Console.WriteLine("key: " + kvp.Key);
Console.WriteLine("values: " + theElement.Symbol + " " +
theElement.Name + " " + theElement.AtomicNumber);
}
}
public class Element
{
public required string Symbol { get; init; }
public required string Name { get; init; }
public required int AtomicNumber { get; init; }
}
private static Dictionary<string, Element> BuildDictionary() =>
new ()
{
{"K",
new (){ Symbol="K", Name="Potassium", AtomicNumber=19}},
{"Ca",
new (){ Symbol="Ca", Name="Calcium", AtomicNumber=20}},
{"Sc",
new (){ Symbol="Sc", Name="Scandium", AtomicNumber=21}},
{"Ti",
new (){ Symbol="Ti", Name="Titanium", AtomicNumber=22}}
};
Az alábbi példa az ContainsKey elem kulcs szerinti gyors megkeresésének módszerét és Item[] tulajdonságát Dictionary használja. A Item tulajdonság lehetővé teszi a gyűjtemény egy elemének elérését a elementselements[symbol] C#-ban.
if (elements.ContainsKey(symbol) == false)
{
Console.WriteLine(symbol + " not found");
}
else
{
Element theElement = elements[symbol];
Console.WriteLine("found: " + theElement.Name);
}
Az alábbi példa a TryGetValue metódussal gyorsan megkeres egy elemet kulcs alapján.
if (elements.TryGetValue(symbol, out Element? theElement) == false)
Console.WriteLine(symbol + " not found");
else
Console.WriteLine("found: " + theElement.Name);
Iterátorok
Az iterátor használatával egyéni iterációt hajthat végre egy gyűjteményen keresztül. Az iterátor lehet módszer vagy get tartozék. Az iterátor hozamvisszautasítást használ a gyűjtemény egyes elemeinek egyenkénti visszaadásához.
Egy foreach utasítással meghívhat egy iterátort. A hurok minden iterációja foreach meghívja az iterátort.
yield return Amikor az iterátor egy utasítást ér el, a rendszer visszaad egy kifejezést, és megtartja a kód aktuális helyét. A végrehajtás attól a helyről indul újra, amikor a következő alkalommal meghívják az iterátort.
További információ: Iterators (C#).
Az alábbi példa egy iterátormetódust használ. Az iterátor metódus egy yield return cikluson belüli utasítással for rendelkezik. A metódusban az ListEvenNumbers utasítás törzsének minden iterációja foreach létrehoz egy hívást az iterátor metódushoz, amely a következő yield return utasításra folytatódik.
private static void ListEvenNumbers()
{
foreach (int number in EvenSequence(5, 18))
{
Console.Write(number.ToString() + " ");
}
Console.WriteLine();
// Output: 6 8 10 12 14 16 18
}
private static IEnumerable<int> EvenSequence(
int firstNumber, int lastNumber)
{
// Yield even numbers in the range.
for (var number = firstNumber; number <= lastNumber; number++)
{
if (number % 2 == 0)
{
yield return number;
}
}
}
LINQ és gyűjtemények
A gyűjtemények eléréséhez használhat nyelvvel integrált lekérdezést (LINQ). A LINQ-lekérdezések szűrési, rendezési és csoportosítási képességeket biztosítanak. További információ: A LINQ használatának első lépései a C#-ban.
Az alábbi példa linq-lekérdezést futtat egy általános List. A LINQ-lekérdezés egy másik gyűjteményt ad vissza, amely tartalmazza az eredményeket.
private static void ShowLINQ()
{
List<Element> elements = BuildList();
// LINQ Query.
var subset = from theElement in elements
where theElement.AtomicNumber < 22
orderby theElement.Name
select theElement;
foreach (Element theElement in subset)
{
Console.WriteLine(theElement.Name + " " + theElement.AtomicNumber);
}
// Output:
// Calcium 20
// Potassium 19
// Scandium 21
}
private static List<Element> BuildList() => new()
{
{ new(){ Symbol="K", Name="Potassium", AtomicNumber=19}},
{ new(){ Symbol="Ca", Name="Calcium", AtomicNumber=20}},
{ new(){ Symbol="Sc", Name="Scandium", AtomicNumber=21}},
{ new(){ Symbol="Ti", Name="Titanium", AtomicNumber=22}}
};