Tulajdonság- és pozícióminták

Tip

Ez a cikk az Alapismeretek szakasz része azon fejlesztők számára, akik már legalább egy programozási nyelvet ismernek, és c#-t tanulnak. Kezdje a mintaegyeztetés áttekintésével , ha a minták újak Önnek. A teljes nyelvi szabályokért tekintse meg a tulajdonságmintákat és a pozíciómintákat a nyelvi referenciaban.

A tulajdonság- és pozícióminták egy érték mindkét részét tesztelik. A különbség az, hogy hogyan azonosítják ezeket a részeket:

  • A tulajdonságminta a tesztelni kívánt tulajdonságokat vagy mezőket nevezi el.
  • A pozícióminta az értékeket a sorrendjük alapján azonosítja.

A destrukció az összetevőértékek rendezett készletét teszi elérhetővé. A tuple-nek már eleve van elemsorrendje; lásd: a tuple-ök visszafejtése. Egy másik típus esetében a Deconstruct metódus határozza meg, hogy mely összetevők értékei lesznek közzétéve, és milyen sorrendben.

Nevek és pozíciók összehasonlítása

Az alábbi tulajdonságminta az időjárás-olvasás két elnevezett tulajdonságát teszteli, celsius fokban megadott hőmérsékleti értékekkel:

static bool IsHotAndHumid(WeatherReading reading) =>
    reading is { TemperatureC: > 30, HumidityPercent: > 70 };

sealed record WeatherReading(int TemperatureC, int HumidityPercent);

A következő pozícióminta egy jelértéket, majd egy logikai értéket tesztel:

static string GetCrossingInstruction(
    PedestrianSignal signal, bool crossingIsClear) =>
    (signal, crossingIsClear) switch
    {
        (PedestrianSignal.Walk, true) => "Cross now",
        (PedestrianSignal.Walk, false) => "Wait for the crossing to clear",
        _ => "Wait for the walk signal"
    };

enum PedestrianSignal
{
    Stop,
    Walk
}

A tulajdonságminta a bemeneteit a TemperatureC és HumidityPercent nevek alapján azonosítja. A keresztező kód tuple-t hoz létre a különálló signal és crossingIsClear értékekből. A tuple-minta ezután a sorrendjük alapján azonosítja ezeket az értékeket: először signal, másodszor crossingIsClear. A pozicionális minta jó választás, mert ez az újonnan létrehozott tuple csak két értéket tartalmaz, és a sorrendjüknek egyértelmű jelentősége van a keresztezés eldöntésében.

Válasszon tulajdonságmintát, ha a tagnevek segítenek elmagyarázni a tesztet. A tulajdonságminták általában világosabbak az osztályok, a szerkezetek és a rekordok esetében. Válasszon egy pozíciómintát, ha a sorrend már egyértelmű jelentést ad az értékeknek. A pozicionális minták leginkább az n-adatoknál hasznosak, amelyek több kapcsolódó értéket egyetlen, rögzített sorrendű értékké kombinálnak.

Beágyazott bemenetek követése rekurzív mintákban

A tulajdonság- és pozícióminták rekurzív minták: Minden kiválasztott tulajdonságra, mezőre vagy pozícióra egy másik mintát alkalmaznak. A kijelölt érték lesz a beágyazott minta bemenete.

Ebben IsHotAndHumida reading kifejezés a tulajdonságminta bemenete. A C# kiértékeli a kifejezést az egyeztetés előtt. A minta két értéket kap az eredményül kapott objektumból:

  • A > 30 relációs minta a TemperatureC értékét vizsgálja.
  • A(z) > 70 relációs minta a(z) HumidityPercent értékét teszteli.

A külső típusteszt nem kötelező, és a rekurzív minta záradékai üresek is lehetnek. Az üres tulajdonságminta { } például megfelel a nem null értékű kiértékelt értékeknek.

A tulajdonság- és pozícióminták csak a nem null értékű kiértékelt értékekkel egyeznek meg. Ha null a bemeneti tartomány része, válasszon egy rekurzív mintát, amely először nem null értéket keres:

static string DescribeNullableInput(object? value)
{
    if (value is not { } nonNullValue)
    {
        return "No value";
    }

    return nonNullValue switch
    {
        DateTime => "Date",
        string => "Text",
        _ => "Another type"
    };
}

A bemeneti kifejezés a következő value: . A C# kiértékeli azt, és a { } tulajdonságminta az eredményül kapott értéket nem null voltára ellenőrzi, mielőtt azt hozzárendelné a nonNullValue változóhoz. Az alábbi kapcsolókifejezés ezután több lehetséges futtatókörnyezet-típust is tesztelhet. A DateTime és string típusminták nem kapnak megjelölést, mert a metódusnak csak az egyes típusokat kell azonosítania, nem pedig az értéküket rögzítenie.

Ha a rekurzív minta záradékok beágyazott mintákat tartalmaznak, minden kijelölt tulajdonság, mező vagy pozíció a beágyazott minta bemenetévé válik.

A kapcsos zárójelek előtt típustesztet adhat hozzá, ha a bemeneti kifejezés különböző típusokat képes előállítani. Egy tag elérési útján is tesztelheti a beágyazott tulajdonságokat:

static string DescribeDate(object? value) =>
    value switch
    {
        DateTime { Date.DayOfWeek:
            DayOfWeek.Saturday or DayOfWeek.Sunday } => "Weekend date",
        DateTime => "Weekday date",
        null => "No date",
        _ => "Not a date"
    };

value a bemeneti kifejezés. A C# először kiértékeli azt, majd megvizsgálja, hogy az így kapott érték DateTime-e. A Date tulajdonság értéke ezután a taghozzáférés DayOfWeek bemenete lesz. Végül az DayOfWeek érték lesz a két állandót tesztelő logikai minta bemenete. Az egyeztetés akkor sikeres, ha a külső érték a megadott típussal rendelkezik, és a tag elérési útja mentén szükséges összes objektum nem null értékű.

Minták összehasonlítása elágaztatási utasításokkal

A korábbi DescribeDate módszer négy eredményt ad ki mintaként:

static string DescribeDate(object? value) =>
    value switch
    {
        DateTime { Date.DayOfWeek:
            DayOfWeek.Saturday or DayOfWeek.Sunday } => "Weekend date",
        DateTime => "Weekday date",
        null => "No date",
        _ => "Not a date"
    };

Az alábbi módszer ugyanazokat az eredményeket hozza létre imperatív elágaztatási utasítások sorozatával:

static string DescribeDateWithBranches(object? value)
{
    if (value is DateTime date)
    {
        if (date.DayOfWeek == DayOfWeek.Saturday ||
            date.DayOfWeek == DayOfWeek.Sunday)
        {
            return "Weekend date";
        }

        return "Weekday date";
    }

    if (value is null)
    {
        return "No date";
    }

    return "Not a date";
}

A mintaalapú verzió együtt tartja a lehetséges eredményeket, amikor több ág teszteli egy érték típusát és alakját. Az imperatív verzió minden tesztelési és visszatérési lépést explicitvá tesz. Egy feltétel esetén mindkét forma hasonlónak tűnhet. A kapcsolódó ágak számának növekedésével a minták megkönnyítik az alternatívák összehasonlítását.

Lásd még