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.
Mintaegyezés – a
A kifejezést, a iskapcsolóutasítást és a kapcsolókifejezést használva tetszőleges számú jellemzővel egyezhet meg egy bemeneti kifejezéssel. A C# több mintát is támogat, beleértve a deklarációt, a típust, az állandót, a relációs, a tulajdonságot, a listát, a var- és az elvetési mintát. A minták logikai logikai kulcsszavak és andornot.
A következő C#-kifejezések és -utasítások támogatják a mintaegyezést:
Ezekben a szerkezetekben egy bemeneti kifejezést az alábbi minták bármelyikével egyezhet meg:
- Deklarációs minta: ellenőrizze egy kifejezés futásidejű típusát, és ha egy egyezés sikeres, rendeljen hozzá egy kifejezés eredményét egy deklarált változóhoz.
- Típusminta: egy kifejezés futásidejű típusának ellenőrzése.
- Állandó minta: annak tesztelése, hogy egy kifejezés eredménye egy megadott állandóval egyenlő-e.
- Relációs minták: egy kifejezés eredményének összehasonlítása egy megadott állandóval.
- Logikai minták: annak tesztelése, hogy egy kifejezés megfelel-e a minták logikai kombinációjának.
- Tulajdonságminta: annak ellenőrzése, hogy egy kifejezés tulajdonságai vagy mezői megegyeznek-e a beágyazott mintákkal.
- Pozícióminta: bontsa ki a kifejezés eredményét, és ellenőrizze, hogy az eredményként kapott értékek megfelelnek-e a beágyazott mintáknak.
-
varminta: egyezzen egy kifejezéssel, és rendelje hozzá az eredményét egy deklarált változóhoz. - Elvetési minta: egyezik bármely kifejezéssel.
- Listaminták: annak tesztelése, hogy az elemek sorozata megfelel-e a megfelelő beágyazott mintáknak.
A logikai, tulajdonság-, pozíció- és listaminták rekurzív minták. Vagyis beágyazott mintákat tartalmazhatnak.
Az ilyen minták adatvezérelt algoritmusok létrehozásához való használatára vonatkozó példa: Oktatóanyag: Típusalapú és adatvezérelt algoritmusok létrehozása mintaegyeztetés használatával.
Deklarálási és típusminták
Deklarációs és típusmintákkal ellenőrizheti, hogy egy kifejezés futásidejű típusa kompatibilis-e egy adott típussal. Deklarációs mintával új helyi változót is deklarálhat. Ha egy deklarációs minta megfelel egy kifejezésnek, az adott változó hozzá lesz rendelve a konvertált kifejezés eredményéhez, ahogy az alábbi példa is mutatja:
object greeting = "Hello, World!";
if (greeting is string message)
{
Console.WriteLine(message.ToLower()); // output: hello, world!
}
A akkor egyezik meg egy kifejezéssel, ha egy kifejezés eredménye nem null, és az alábbi feltételek bármelyike igaz:
- A kifejezés eredményének futásidejű típusa identitásátalakítással
Trendelkezik. - A típus
Tegyref structtípus, és a kifejezésbőlTidentitásátalakítás történik. - A kifejezés eredményének futásidejű típusa típusból
T, implementálási felületbőlTszármazik, vagy egy másik implicit referenciakonvertálás létezik belőleT. Ez az öröklési kapcsolatokat és a felület implementációit ismerteti. Az alábbi példa két esetet mutat be, amikor ez a feltétel igaz:
Az előző példában a metódus első hívásánálvar numbers = new int[] { 10, 20, 30 }; Console.WriteLine(GetSourceLabel(numbers)); // output: 1 var letters = new List<char> { 'a', 'b', 'c', 'd' }; Console.WriteLine(GetSourceLabel(letters)); // output: 2 static int GetSourceLabel<T>(IEnumerable<T> source) => source switch { Array array => 1, ICollection<T> collection => 2, _ => 3, };GetSourceLabelaz első minta egy argumentumértéknek felel meg, mert az argumentum futásidejének típusaint[]a Array típusból származik. A metódus második hívásánálGetSourceLabelaz argumentum futásidejének típusa List<T> nem a Array típusból származik, hanem implementálja az interfészt ICollection<T> . - A kifejezés eredményének futásidejű típusa egy nullázható értéktípus az alapul szolgáló típussal
T, és a Nullable<T>.HasValue jellemzője atrue. - A kifejezés eredményének futásidejű típusából boxing vagy unboxing konverzió létezhet
Ttípusba, ha a kifejezés nem egyref structpéldány.
A deklarációs minták nem veszik figyelembe a felhasználó által definiált konverziókat vagy implicit span konverziókat.
Az alábbi példa az utolsó két feltételt mutatja be:
int? xNullable = 7;
int y = 23;
object yBoxed = y;
if (xNullable is int a && yBoxed is int b)
{
Console.WriteLine(a + b); // output: 30
}
Ha csak a kifejezés típusát szeretné ellenőrizni, használhatja a változó nevének elvetése _ helyett, ahogy az alábbi példa is mutatja:
public abstract class Vehicle {}
public class Car : Vehicle {}
public class Truck : Vehicle {}
public static class TollCalculator
{
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car _ => 2.00m,
Truck _ => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
}
Ehhez típusmintát használhat, ahogy az alábbi példa is mutatja:
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car => 2.00m,
Truck => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
A deklarációs mintához hasonlóan a típusminta akkor felel meg egy kifejezésnek, ha egy kifejezés eredménye nem null, és futásideje megfelel az előző feltételek bármelyikének.
Ha nem null értéket szeretne keresni, használjon negated null állandó mintát, ahogy az alábbi példa is mutatja:
if (input is not null)
{
// ...
}
További információ: A funkciójavaslat megjegyzéseinek Deklarációs minta és Típusminta szakasza.
Állandó minta
Az állandó minta egy alternatív szintaxis == , ha a megfelelő operandus állandó.
Állandó mintával tesztelheti, hogy egy kifejezés eredménye egy megadott állandóval egyenlő-e, ahogy az alábbi példa is mutatja:
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
1 => 12.0m,
2 => 20.0m,
3 => 27.0m,
4 => 32.0m,
0 => 0.0m,
_ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
Állandó mintában bármilyen állandó kifejezést használhat, például:
- egész szám vagy lebegőpontos numerikus literál
- karakter
- sztringkonstans.
- logikai érték
truevagyfalse - enumerálási érték
- deklarált const mező vagy helyi neve
null
A kifejezésnek olyan típusnak kell lennie, amely konstanstípussá konvertálható, egyetlen kivétellel: Olyan kifejezés, amelynek típusa Span<char> állandó sztringekkel egyeztethető vagy ReadOnlySpan<char> megfeleltethető.
A kereséshez nullhasználjon állandó mintát, ahogyan az az alábbi példában látható:
if (input is null)
{
return;
}
A fordító garantálja, hogy a kifejezés == kiértékelésekor a rendszer nem hív meg felhasználó által túlterhelt egyenlőségi operátortx is null.
A nem null értékű állandók ellenőrzéséhez negated, ahogy az alábbi példa is mutatja:
if (input is not null)
{
// ...
}
További információkért tekintse meg a funkciójavaslat megjegyzésének Állandó minta szakaszát.
Relációs minták
Relációs mintát használ egy kifejezés eredményének konstanssal való összehasonlításához, ahogy az alábbi példa is mutatja:
Console.WriteLine(Classify(13)); // output: Too high
Console.WriteLine(Classify(double.NaN)); // output: Unknown
Console.WriteLine(Classify(2.4)); // output: Acceptable
static string Classify(double measurement) => measurement switch
{
< -4.0 => "Too low",
> 10.0 => "Too high",
double.NaN => "Unknown",
_ => "Acceptable",
};
Relációs mintában a relációs operátorok bármelyikét < A relációs minta jobb oldali részének állandó kifejezésnek kell lennie. Az állandó kifejezés lehet egész szám, lebegőpontos, karakter vagy szám típusú.
Ha ellenőrizni szeretné, hogy egy kifejezés eredménye egy adott tartományba tartozik-e, egy kötőhártya-mintával andkell-e egyeznie, ahogy az alábbi példa mutatja:
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 3, 14))); // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 7, 19))); // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 2, 17))); // output: winter
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Ha egy kifejezés eredménye null null értékű vagy nem egyező konverzióval konstans típusúvá alakul, a relációs minta nem egyezik meg egy kifejezéssel.
További információkért tekintse meg a funkciójavaslat megjegyzésének Relációs minták szakaszát.
Logikai minták
A , és minta notkombinátorokkal a következő and hozhatja or létre:
Olyan tagadási
notminta, amely megfelel egy kifejezésnek, ha a negated minta nem egyezik meg a kifejezéssel. Az alábbi példa bemutatja, hogyan tagadhat meg egy állandónullmintát annak ellenőrzéséhez, hogy egy kifejezés nem null értékű-e:if (input is not null) { // ... }Kötőjeles
andminta, amely akkor felel meg egy kifejezésnek, ha mindkét minta megegyezik a kifejezéssel. Az alábbi példa bemutatja, hogyan kombinálhatja a relációs mintákat annak ellenőrzéséhez, hogy egy érték egy adott tartományban van-e:Console.WriteLine(Classify(13)); // output: High Console.WriteLine(Classify(-100)); // output: Too low Console.WriteLine(Classify(5.7)); // output: Acceptable static string Classify(double measurement) => measurement switch { < -40.0 => "Too low", >= -40.0 and < 0 => "Low", >= 0 and < 10.0 => "Acceptable", >= 10.0 and < 20.0 => "High", >= 20.0 => "Too high", double.NaN => "Unknown", };Disjunctive
orpattern, amely megfelel egy kifejezésnek, ha bármelyik minta megegyezik a kifejezéssel, ahogy az alábbi példa mutatja:Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); // output: winter Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); // output: autumn Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); // output: spring static string GetCalendarSeason(DateTime date) => date.Month switch { 3 or 4 or 5 => "spring", 6 or 7 or 8 => "summer", 9 or 10 or 11 => "autumn", 12 or 1 or 2 => "winter", _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."), };
Ahogy az előző példa is mutatja, a mintakombinátorokat többször is használhatja egy mintában.
Az ellenőrzés sorrendje és sorrendje
A minta-kombinátorok a kifejezések kötési sorrendje alapján vannak rendezve az alábbiak szerint:
notandor
A not minta először az operandusához kötődik. A and minta minden not mintakifejezés kötése után megköt. A or minta végül not is kötődik, és and a minták operandusokhoz vannak kötve. Az alábbi példa az összes olyan karaktert megpróbálja egyezni, amely nem kisbetű. a - z Hiba történt, mert a not minta a minta előtt and kötődik:
// Incorrect pattern. `not` binds before `and`
static bool IsNotLowerCaseLetter(char c) => c is not >= 'a' and <= 'z';
Az alapértelmezett kötés azt jelenti, hogy az előző példa a következő példaként van elemezve:
// The default binding without parentheses is shows in this method. `not` binds before `and`
static bool IsNotLowerCaseLetterDefaultBinding(char c) => c is ((not >= 'a') and <= 'z');
A javításhoz meg kell adnia, hogy a not kifejezést a következőhöz >= 'a' and <= 'z' szeretné kötni:
// Correct pattern. Force `and` before `not`
static bool IsNotLowerCaseLetterParentheses(char c) => c is not (>= 'a' and <= 'z');
A zárójelek hozzáadása egyre fontosabbá válik, mivel a minták egyre bonyolultabbá válnak. Általában zárójelekkel egyértelműsítse a mintákat más fejlesztők számára, ahogy az alábbi példa is mutatja:
static bool IsLetter(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
Feljegyzés
Az azonos kötési sorrendű minták ellenőrzésének sorrendje nincs meghatározva. Futásidőben a több mintából és több orand mintából álló jobb oldali beágyazott minták először ellenőrizhetők.
További információkért tekintse meg a funkciójavaslat megjegyzésének Minta kombinatorok szakaszát.
Tulajdonságminta
Tulajdonságmintával egyezik meg egy kifejezés tulajdonságaival vagy mezőivel a beágyazott mintázatokkal, ahogy az alábbi példa is mutatja:
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
A tulajdonságminta akkor egyezik meg egy kifejezéssel, ha egy kifejezés eredménye nem null, és minden beágyazott minta megegyezik a kifejezés eredményének megfelelő tulajdonságával vagy mezőjével.
A tulajdonságmintákhoz futásidejű típusellenőrzést és változódeklarációt is hozzáadhat, ahogy az alábbi példa is mutatja:
Console.WriteLine(TakeFive("Hello, world!")); // output: Hello
Console.WriteLine(TakeFive("Hi!")); // output: Hi!
Console.WriteLine(TakeFive(new[] { '1', '2', '3', '4', '5', '6', '7' })); // output: 12345
Console.WriteLine(TakeFive(new[] { 'a', 'b', 'c' })); // output: abc
static string TakeFive(object input) => input switch
{
string { Length: >= 5 } s => s.Substring(0, 5),
string s => s,
ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
ICollection<char> symbols => new string(symbols.ToArray()),
null => throw new ArgumentNullException(nameof(input)),
_ => throw new ArgumentException("Not supported input type."),
};
Ez a szerkezet kifejezetten azt jelenti, hogy az üres tulajdonságminta is { } minden nem null értékű tulajdonságnak felel meg, és a is not null változó létrehozása helyett használható: somethingPossiblyNull is { } somethingDefinitelyNotNull.
if (GetSomeNullableStringValue() is { } nonNullValue) // Empty property pattern with variable creation
{
Console.WriteLine("NotNull:" + nonNullValue);
}
else
{
nonNullValue = "NullFallback"; // we can access the variable here.
Console.WriteLine("it was null, here's the fallback: " + nonNullValue);
}
A tulajdonságminta rekurzív minta. Bármilyen mintát használhat beágyazott mintaként. Tulajdonságmintával egyezhet az adatok egyes részeivel a beágyazott mintákkal, ahogy az alábbi példa is mutatja:
public record Point(int X, int Y);
public record Segment(Point Start, Point End);
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start: { Y: 0 } } or { End: { Y: 0 } };
Az előző példa a minta-kombinátort és a orrekordtípusokat használja.
Beágyazott tulajdonságokra vagy mezőkre hivatkozhat egy tulajdonságmintán belül. Ezt a képességet kiterjesztett tulajdonságmintának nevezzük. Az előző példában szereplő metódust például újrafunkálhatja a következő egyenértékű kódba:
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start.Y: 0 } or { End.Y: 0 };
További információ: A funkciójavaslat megjegyzésének Tulajdonságminta szakasza és a Kiterjesztett tulajdonságminták funkciójavaslat megjegyzése.
Tipp.
A Tulajdonságminta egyszerűsítése (IDE0170) stílusszabálysal javíthatja a kód olvashatóságát, ha kiterjesztett tulajdonságminták használatára javasol helyeket.
Pozícióminta
Pozíciómintát használ egy kifejezés eredményének dekonstruálásához, és megfelelteti az eredményként kapott értékeket a megfelelő beágyazott mintákhoz, ahogyan az alábbi példa mutatja:
public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
static string Classify(Point point) => point switch
{
(0, 0) => "Origin",
(1, 0) => "positive X basis end",
(0, 1) => "positive Y basis end",
_ => "Just a point",
};
Az előző példában egy kifejezés típusa tartalmazza a Deconstruct metódust, amely egy kifejezés eredményének dekonstruálására szolgál.
Fontos
A pozíciómintában szereplő tagok sorrendjének meg kell egyeznie a Deconstruct metódus paramétereinek sorrendjével. A pozíciómintához létrehozott kód meghívja a metódust Deconstruct .
A rekordtípusok kifejezéseit a pozíciómintákhoz is igazíthatja. Így több bemenetet is egyeztethet különböző mintákkal, ahogy az alábbi példa is mutatja:
static decimal GetGroupTicketPriceDiscount(int groupSize, DateTime visitDate)
=> (groupSize, visitDate.DayOfWeek) switch
{
(<= 0, _) => throw new ArgumentException("Group size must be positive."),
(_, DayOfWeek.Saturday or DayOfWeek.Sunday) => 0.0m,
(>= 5 and < 10, DayOfWeek.Monday) => 20.0m,
(>= 10, DayOfWeek.Monday) => 30.0m,
(>= 5 and < 10, _) => 12.0m,
(>= 10, _) => 15.0m,
_ => 0.0m,
};
Az előző példa relációs és logikai mintákat használ.
A rekordelemek és Deconstruct paraméterek neveit egy pozíciómintában használhatja, ahogy az alábbi példa is mutatja:
var numbers = new List<int> { 1, 2, 3 };
if (SumAndCount(numbers) is (Sum: var sum, Count: > 0))
{
Console.WriteLine($"Sum of [{string.Join(" ", numbers)}] is {sum}"); // output: Sum of [1 2 3] is 6
}
static (double Sum, int Count) SumAndCount(IEnumerable<int> numbers)
{
int sum = 0;
int count = 0;
foreach (int number in numbers)
{
sum += number;
count++;
}
return (sum, count);
}
A pozíciómintát az alábbi módokon is kiterjesztheti:
Adjon hozzá egy futásidejű típusellenőrzést és egy változódeklarációt az alábbi példában látható módon:
public record Point2D(int X, int Y); public record Point3D(int X, int Y, int Z); static string PrintIfAllCoordinatesArePositive(object point) => point switch { Point2D (> 0, > 0) p => p.ToString(), Point3D (> 0, > 0, > 0) p => p.ToString(), _ => string.Empty, };Az előző példa olyan pozíciórekordokat használ, amelyek implicit módon biztosítják a metódust
Deconstruct.Használjon tulajdonságmintát egy pozíciómintán belül, ahogyan az az alábbi példában látható:
public record WeightedPoint(int X, int Y) { public double Weight { get; set; } } static bool IsInDomain(WeightedPoint point) => point is (>= 0, >= 0) { Weight: >= 0.0 };Két előző használat kombinálása az alábbi példában látható módon:
if (input is WeightedPoint (> 0, > 0) { Weight: > 0.0 } p) { // .. }
A pozícióminta rekurzív minta. Ez azt is jelentheti, hogy bármilyen mintát használhat beágyazott mintaként.
További információkért tekintse meg a funkciójavaslat megjegyzésének Pozícióminta szakaszát.
var minta
Az alábbi példában látható módon egy var tetszőleges kifejezésnek megfelelő mintát használhat, beleértve nullaz eredményt is, és hozzárendelheti annak eredményét egy új helyi változóhoz:
static bool IsAcceptable(int id, int absLimit) =>
SimulateDataFetch(id) is var results
&& results.Min() >= -absLimit
&& results.Max() <= absLimit;
static int[] SimulateDataFetch(int id)
{
var rand = new Random();
return Enumerable
.Range(start: 0, count: 5)
.Select(s => rand.Next(minValue: -10, maxValue: 11))
.ToArray();
}
A var minta akkor hasznos, ha ideiglenes változóra van szüksége egy logikai kifejezésben a köztes számítások eredményének tárolásához. Akkor is használhat var mintát, ha több ellenőrzést when kell végrehajtania egy switch kifejezés vagy utasítás őrei esetében, ahogy az alábbi példa mutatja:
public record Point(int X, int Y);
static Point Transform(Point point) => point switch
{
var (x, y) when x < y => new Point(-x, y),
var (x, y) when x > y => new Point(x, -y),
var (x, y) => new Point(x, y),
};
static void TestTransform()
{
Console.WriteLine(Transform(new Point(1, 2))); // output: Point { X = -1, Y = 2 }
Console.WriteLine(Transform(new Point(5, 2))); // output: Point { X = 5, Y = -2 }
}
Az előző példában a minta var (x, y) egy pozíciómintával (var x, var y)egyenértékű.
var A mintában a deklarált változó típusa annak a kifejezésnek a fordítási ideje, amely megfelel a mintának.
További információkért tekintse meg a funkciójavaslat megjegyzésének Var minta szakaszát.
Minta elvetése
Elvetési mintát_ használ bármely kifejezéshez, például nullaz alábbi példában látható módon:
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)); // output: 5.0
Console.WriteLine(GetDiscountInPercent(null)); // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10)); // output: 0.0
static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
DayOfWeek.Monday => 0.5m,
DayOfWeek.Tuesday => 12.5m,
DayOfWeek.Wednesday => 7.5m,
DayOfWeek.Thursday => 12.5m,
DayOfWeek.Friday => 5.0m,
DayOfWeek.Saturday => 2.5m,
DayOfWeek.Sunday => 2.0m,
_ => 0.0m,
};
Az előző példában a rendszer elvetési mintát használ null , és minden olyan egész számértéket, amely nem rendelkezik az DayOfWeek enumerálás megfelelő tagjával. Ez garantálja, hogy switch a példában szereplő kifejezés minden lehetséges bemeneti értéket kezel. Ha nem használ elvetési mintát egy switch kifejezésben, és a kifejezés egyik mintája sem egyezik meg egy bemenettel, a futtatókörnyezet kivételt jelez. A fordító figyelmeztetést generál, ha egy switch kifejezés nem kezeli az összes lehetséges bemeneti értéket.
Az elvetési minta nem lehet minta egy is kifejezésben vagy utasításban switch . Ezekben az esetekben a kifejezések egyeztetéséhez használjon egy var mintát egy elvetéssel: var _. Az elvetési minta egy kifejezés mintája switch lehet.
További információ: A funkciójavaslat megjegyzésének Minta elvetése szakasza.
Zárójeles minta
Zárójeleket bármilyen minta köré helyezhet. Ezt általában a logikai minták elsőbbségének hangsúlyozására vagy módosítására kell elvégeznie, ahogyan az alábbi példa is mutatja:
if (input is not (float or double))
{
return;
}
Listaminták
Egy tömböt vagy listát egy mintasorozattal egyezhet meg, ahogy az alábbi példa is mutatja:
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers is [1, 2, 3]); // True
Console.WriteLine(numbers is [1, 2, 4]); // False
Console.WriteLine(numbers is [1, 2, 3, 4]); // False
Console.WriteLine(numbers is [0 or 1, <= 2, >= 3]); // True
Ahogy az előző példa is mutatja, a listaminta akkor egyezik meg, ha minden beágyazott minta megegyezik egy bemeneti sorozat megfelelő elemével. A listamintán belül bármilyen mintát használhat. Bármely elemnek megfeleltetheti az elvetési mintát , vagy ha az elemet is rögzíteni szeretné, a varmintát, ahogyan az alábbi példa mutatja:
List<int> numbers = new() { 1, 2, 3 };
if (numbers is [var first, _, _])
{
Console.WriteLine($"The first element of a three-item list is {first}.");
}
// Output:
// The first element of a three-item list is 1.
Az előző példák egy teljes bemeneti sorozatot egy listamintával egyeznek meg. Ha csak a bemeneti sorozat elején vagy végén szeretne elemeket egyeztetni, használja a szeletmintát.., ahogyan az az alábbi példában látható:
Console.WriteLine(new[] { 1, 2, 3, 4, 5 } is [> 0, > 0, ..]); // True
Console.WriteLine(new[] { 1, 1 } is [_, _, ..]); // True
Console.WriteLine(new[] { 0, 1, 2, 3, 4 } is [> 0, > 0, ..]); // False
Console.WriteLine(new[] { 1 } is [1, 2, ..]); // False
Console.WriteLine(new[] { 1, 2, 3, 4 } is [.., > 0, > 0]); // True
Console.WriteLine(new[] { 2, 4 } is [.., > 0, 2, 4]); // False
Console.WriteLine(new[] { 2, 4 } is [.., 2, 4]); // True
Console.WriteLine(new[] { 1, 2, 3, 4 } is [>= 0, .., 2 or 4]); // True
Console.WriteLine(new[] { 1, 0, 0, 1 } is [1, 0, .., 0, 1]); // True
Console.WriteLine(new[] { 1, 0, 1 } is [1, 0, .., 0, 1]); // False
A szeletminta nulla vagy több elemnek felel meg. A listamintában legfeljebb egy szeletmintát használhat. A szeletminta csak listamintában jelenhet meg.
Egy alpattert egy szeletmintán belül is beágyazhat, ahogy az alábbi példa is mutatja:
void MatchMessage(string message)
{
var result = message is ['a' or 'A', .. var s, 'a' or 'A']
? $"Message {message} matches; inner part is {s}."
: $"Message {message} doesn't match.";
Console.WriteLine(result);
}
MatchMessage("aBBA"); // output: Message aBBA matches; inner part is BB.
MatchMessage("apron"); // output: Message apron doesn't match.
void Validate(int[] numbers)
{
var result = numbers is [< 0, .. { Length: 2 or 4 }, > 0] ? "valid" : "not valid";
Console.WriteLine(result);
}
Validate(new[] { -1, 0, 1 }); // output: not valid
Validate(new[] { -1, 0, 0, 1 }); // output: valid
További információ: List patterns feature proposal note.
C# nyelvspecifikáció
További információkért tekintse meg a C# nyelvspecifikáció mintáit és mintázatmegfeleltetésiszakaszát.
A C# 8-ban és újabb verziókban hozzáadott funkciókkal kapcsolatos információkért tekintse meg a következő funkciójavaslat-megjegyzéseket:
- Mintaegyeztetési frissítések
- kiterjesztett tulajdonságminták
- Listaminták
-
Mintaegyezés
Span<char>sztringkonstanson