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 kivetítés egy objektum új formává alakításának műveletére utal, amely gyakran csak azokból a tulajdonságokból áll, amelyeket később használnak. A kivetítés használatával létrehozhat egy új típust, amely az egyes objektumokból épül fel. Kivetíthet egy tulajdonságot, és matematikai függvényt is végrehajthat rajta. Az eredeti objektumot módosítás nélkül is kivetítheti.
Fontos
Ezek a minták adatforrást System.Collections.Generic.IEnumerable<T> használnak. A System.Linq.IQueryProvider alapú adatforrások a System.Linq.IQueryable<T> adatforrásokat és a kifejezésfákat használják. A kifejezésfák korlátozottan használhatják az engedélyezett C# szintaxist. Emellett minden adatforrás IQueryProvider , például az EF Core további korlátozásokat is alkalmazhat. Ellenőrizze az adatforrás dokumentációját.
A vetítést végző szabványos lekérdezési operátor-metódusok a következő szakaszban találhatók.
Módszerek
| Metódusnevek | Leírás | C# lekérdezési kifejezés szintaxisa | További információ |
|---|---|---|---|
| Válassza ki | Transzformációs függvényen alapuló projektek értékei. | select |
Enumerable.Select Queryable.Select |
| SelectMany | Transzformációs függvényen alapuló értéksorozatokat projektel, majd egy sorozatba simítja őket. | Több from záradék használata |
Enumerable.SelectMany Queryable.SelectMany |
| Fütyülés | 2–3 megadott sorozat elemeit tartalmazó üstöksorozatot hoz létre. | Nem alkalmazható. | Enumerable.Zip Queryable.Zip |
Select
Az alábbi példa a select záradék használatával veti ki az egyes sztringek első betűit a sztringek listájában.
Megjegyzés:
A terület gyakori adatforrásai a Standard lekérdezési operátorok áttekintése című cikkben találhatóak.
List<string> words = ["an", "apple", "a", "day"];
var query = from word in words
select word.Substring(0, 1);
foreach (string s in query)
{
Console.WriteLine(s);
}
/* This code produces the following output:
a
a
a
d
*/
A metódusszintaxissal egyenértékű lekérdezés a következő kódban jelenik meg:
List<string> words = ["an", "apple", "a", "day"];
var query = words.Select(word => word.Substring(0, 1));
foreach (string s in query)
{
Console.WriteLine(s);
}
/* This code produces the following output:
a
a
a
d
*/
SelectMany
Az alábbi példa több különböző from záradékot használ a sztringek listájában lévő minden sztring minden szavának kivetítéséhez.
List<string> phrases = ["an apple a day", "the quick brown fox"];
var query = from phrase in phrases
from word in phrase.Split(' ')
select word;
foreach (string s in query)
{
Console.WriteLine(s);
}
/* This code produces the following output:
an
apple
a
day
the
quick
brown
fox
*/
A metódusszintaxissal egyenértékű lekérdezés a következő kódban jelenik meg:
List<string> phrases = ["an apple a day", "the quick brown fox"];
var query = phrases.SelectMany(phrase => phrase.Split(' '));
foreach (string s in query)
{
Console.WriteLine(s);
}
/* This code produces the following output:
an
apple
a
day
the
quick
brown
fox
*/
A SelectMany metódus az első sorozat minden elemének és a második sorozat minden elemének összeillesztésének kombinációját is alkothatja:
var query = from number in numbers
from letter in letters
select (number, letter);
foreach (var item in query)
{
Console.WriteLine(item);
}
A metódusszintaxissal egyenértékű lekérdezés a következő kódban jelenik meg:
var method = numbers
.SelectMany(number => letters,
(number, letter) => (number, letter));
foreach (var item in method)
{
Console.WriteLine(item);
}
Zip
A vetítési operátornak Zip számos túlterhelése van.
Zip Az összes metódus két vagy több, esetleg heterogén típusú sorozaton dolgozik. Az első két túlterhelés tuple-okat ad vissza, a megadott szekvenciák megfelelő pozíciótípusával.
Vegye figyelembe a következő gyűjteményeket:
// An int array with 7 elements.
IEnumerable<int> numbers = [1, 2, 3, 4, 5, 6, 7];
// A char array with 6 elements.
IEnumerable<char> letters = ['A', 'B', 'C', 'D', 'E', 'F'];
A sorozatok együtt történő kivetítéséhez használja az operátort Enumerable.Zip<TFirst,TSecond>(IEnumerable<TFirst>, IEnumerable<TSecond>) :
foreach ((int number, char letter) in numbers.Zip(letters))
{
Console.WriteLine($"Number: {number} zipped with letter: '{letter}'");
}
// This code produces the following output:
// Number: 1 zipped with letter: 'A'
// Number: 2 zipped with letter: 'B'
// Number: 3 zipped with letter: 'C'
// Number: 4 zipped with letter: 'D'
// Number: 5 zipped with letter: 'E'
// Number: 6 zipped with letter: 'F'
Fontos
A zip műveletből származó sorozat soha nem hosszabb a legrövidebb sorozatnál. A numbers és letters gyűjtemények hossza eltér, és az eredményül kapott sorozat kihagyja az utolsó elemet a numbers gyűjteményből, mivel nincs semmi, amellyel párosítani lehet.
A második túlterhelés elfogad egy third sorozatot. Hozzunk létre egy másik gyűjteményt, nevezetesen emoji:
// A string array with 8 elements.
IEnumerable<string> emoji = [ "🤓", "🔥", "🎉", "👀", "⭐", "💜", "✔", "💯"];
A sorozatok együtt történő kivetítéséhez használja az operátort Enumerable.Zip<TFirst,TSecond,TThird>(IEnumerable<TFirst>, IEnumerable<TSecond>, IEnumerable<TThird>) :
foreach ((int number, char letter, string em) in numbers.Zip(letters, emoji))
{
Console.WriteLine(
$"Number: {number} is zipped with letter: '{letter}' and emoji: {em}");
}
// This code produces the following output:
// Number: 1 is zipped with letter: 'A' and emoji: 🤓
// Number: 2 is zipped with letter: 'B' and emoji: 🔥
// Number: 3 is zipped with letter: 'C' and emoji: 🎉
// Number: 4 is zipped with letter: 'D' and emoji: 👀
// Number: 5 is zipped with letter: 'E' and emoji: ⭐
// Number: 6 is zipped with letter: 'F' and emoji: 💜
Az előző túlterheléshez hasonlóan a Zip metódus egy három elemből álló n-tuple-t vetít ki.
A harmadik túlterhelés olyan argumentumot Func<TFirst, TSecond, TResult> fogad el, amely eredményválasztóként működik. A tömörített szekvenciákból új eredményül kapott sorozatot is kivetíthet.
foreach (string result in
numbers.Zip(letters, (number, letter) => $"{number} = {letter} ({(int)letter})"))
{
Console.WriteLine(result);
}
// This code produces the following output:
// 1 = A (65)
// 2 = B (66)
// 3 = C (67)
// 4 = D (68)
// 5 = E (69)
// 6 = F (70)
Az előző Zip túlterhelés esetén a megadott függvény a megfelelő elemekre number lesz alkalmazva, és letteraz string eredmények sorozatát eredményezi.
Select és SelectMany
Mindkettő Select feladata, hogy SelectMany eredményértéket (vagy értékeket) állít elő a forrásértékekből.
Select minden forrásértékhez egy eredményértéket állít elő. Az összesített eredmény tehát egy olyan gyűjtemény, amelynek ugyanannyi eleme van, mint a forrásgyűjteménynek. Ezzel szemben egyetlen összesített eredményt hoz létre, SelectMany amely az egyes forrásértékekből származó összefűzött részösszetevőket tartalmazza. Az argumentumként átadott átalakítási függvénynek SelectMany az egyes forrásértékek számbavételes értéksorát kell visszaadnia.
SelectMany összefűzi ezeket az enumerálható sorozatokat egy nagy sorozat létrehozásához.
Az alábbi két ábra a két módszer műveletei közötti fogalmi különbséget mutatja be. Tegyük fel, hogy a választó (átalakító) függvény minden egyes forrásértékből kiválasztja a virágtömböt.
Ez az ábra azt mutatja be, hogyan Select ad vissza egy olyan gyűjteményt, amelynek ugyanannyi eleme van, mint a forrásgyűjteménynek.
Ez az ábra bemutatja, hogyan SelectMany fűzi össze a tömbök köztes sorozatát egy végső eredményértékbe, amely az egyes köztes tömbök minden értékét tartalmazza.
Kódrészlet
Az alábbi példa a Select és a SelectMany viselkedését hasonlítja össze. A kód egy virágcsokrot hoz létre úgy, hogy a forrásgyűjteményben lévő virágnevek minden egyes listájából eltávolítja az elemeket. Az alábbi példában az átalakító függvény Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>) által használt "egyetlen érték" értékgyűjtemény. Ehhez a példához szükség van a további foreach hurokra az egyes alhálózatok sztringjeinek számbavételéhez.
class Bouquet
{
public required List<string> Flowers { get; init; }
}
static void SelectVsSelectMany()
{
List<Bouquet> bouquets =
[
new Bouquet { Flowers = ["sunflower", "daisy", "daffodil", "larkspur"] },
new Bouquet { Flowers = ["tulip", "rose", "orchid"] },
new Bouquet { Flowers = ["gladiolis", "lily", "snapdragon", "aster", "protea"] },
new Bouquet { Flowers = ["larkspur", "lilac", "iris", "dahlia"] }
];
IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);
IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);
Console.WriteLine("Results by using Select():");
// Note the extra foreach loop here.
foreach (IEnumerable<string> collection in query1)
{
foreach (string item in collection)
{
Console.WriteLine(item);
}
}
Console.WriteLine("\nResults by using SelectMany():");
foreach (string item in query2)
{
Console.WriteLine(item);
}
}