Típusmintá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 kompatibilitási szabályokért tekintse meg a nyelvi referencia deklarációs és típusmintáit .

A program típusmintát alkalmaz egy bemeneti kifejezésre. A C# kiértékeli a kifejezést, majd ellenőrzi, hogy az eredményként kapott érték nem null értékű-e, és hogy a futási idő típusa kompatibilis-e a megadott típussal. A típusminta csak azt jelzi, hogy a típusteszt sikeres-e. Nem deklarál változót.

Tegyen fel egy igen-nem kérdést

A szállítási rendszerben IRouteStop az útvonaltervezés által elfogadott célhelyekre vonatkozó képességszerződés. CanRoute ellenőrzi, hogy a kiértékelt cél rendelkezik-e ezzel a képességgel, és logikai eredménye határozza meg, hogy a cél belép-e az útvonaltervezési munkafolyamatba. A munkafolyamatnak csak egy igen vagy nem válaszra van szüksége, és nem olvassa be a route-stop tagokat, így egy rögzített változó nélküli típusminta jól megfelel.

static bool CanRoute(object? destination) =>
    destination is IRouteStop;

A bemeneti kifejezés a(z) destination, és a(z) IRouteStop a tesztelt típus. Válasszon típusmintát, ha a válasz csak igen vagy nem. Ha a megfelelő ágnak címet kell olvasnia, vagy egy másik tagot a(z) IRouteStop használatával kell meghívnia, válasszon helyette egy deklarációs mintát, így az ág rendelkezni fog egy ilyen típusú változóval.

Note

Előfordulhat, hogy a(z) destination is IRouteStop _ is megjelenik. Ez a szintaxis egy deklarációs minta, amely _ azt jelenti, hogy egyetlen változó sem marad meg. Ugyanazt a típustesztet hajtja végre, ha mindkét űrlap érvényes, de destination is IRouteStop közvetlenül a csak tesztelési szándékot állítja be.

Osztályok és felületek egyeztetése

A kézbesítési rendszerben IRouteStop meghatározza az útvonaltervezési célhelyekre vonatkozó képességszerződést, míg RouteStop egy alaposztály, amely általános útvonalleállítási adatokat és megvalósítást biztosít. ExpressRouteStop egy speciális osztály, amely a .-ból RouteStopszármazik. A példa egy kiértékelt értéket tesztel, hogy a kimenete mindhárom kompatibilis típust be tudja mutatni. Minden teszthez csak logikai eredményre van szükség, ezért nincs szükség rögzített változóra.

interface IRouteStop { }

abstract class RouteStop(string street) : IRouteStop
{
    public string Street { get; } = street;

    public string GetDisplayName() => Street;
}

sealed class ExpressRouteStop(string street) : RouteStop(street)
{
}

static void ShowCompatibility()
{
    object destination = new ExpressRouteStop("8 Oak Avenue");

    Console.WriteLine($"Exact class: {destination is ExpressRouteStop}");
    Console.WriteLine($"Base class: {destination is RouteStop}");
    Console.WriteLine($"Interface: {destination is IRouteStop}");
}

A kiértékelt érték egy ExpressRouteStop. A kimenet azt mutatja, hogy megegyezik a saját pontos osztályával, a RouteStop alaposztályával és azzal a IRouteStop felülettel, amelyet a RouteStop valósít meg.

Részletes kompatibilitási szabályokért és peremes esetekért tekintse meg a típusminta-referenciát.

Több típus átirányítása

A támogatási rendszerben SupportRequest az alaposztály a speciális kérésosztályokhoz, például PasswordResetRequest és BillingQuestion. Egy switch-ág egy mintát egy olyan eredménnyel párosít, amelyet a rendszer akkor ad vissza, amikor a minta illeszkedik. Minden kar egy feldolgozási üzenetsor nevét adja vissza, az utolsó kar pedig tartalék üzenetsort biztosít a többi kiértékelt értékhez. A kiválasztott üzenetsor kizárólag a kiértékelt érték futásidejű típusától függ, ezért a típusminták megfelelőek, mert a kérés egyetlen tagját sem olvassuk ki.

static string RouteRequest(object request) =>
    request switch
    {
        PasswordResetRequest => "Identity queue",
        BillingQuestion => "Billing queue",
        SupportRequest => "General support queue",
        _ => "Intake queue"
    };

Minden ág egy típuskérdésre válaszol, és visszaadja az adott kérést kezelő üzenetsort. Ha egy ágnak olvasnia kell a kérés tagjait, deklarációs mintával tárolja el az egyező értéket egy változóban.

A kapcsolókarokat felülről lefelé tekintjük. Helyezzen egy speciális osztályt az alaposztály elé. Ellenkező esetben az alaposztály ága illeszkedhet a specializált osztály összes példányára, ami miatt a későbbi ág elérhetetlenné válik.

Nem kötelező: típusparaméter használata tesztelt típusként

Ez az opcionális példa általános típusokra és metódusokra épül. Egy típusparaméter , például TRequest a hívó által biztosított típus helyőrzője. A bejövő kérelmeket tartalmazó köteg többféle kéréstípust is tartalmazhat, és a hívó a ConfidentialRequest elemet adja meg annak ellenőrzésére, hogy bármelyik kérés bizalmas kezelést igényel-e. A logikai eredmény a teljes köteg bizalmas kezelését választja ki, és látható állapotüzenetet hoz létre. A típusparaméterrel rendelkező típusminta azért illik ide, mert csak az egyező kérés megléte számít, ezért az egyező objektumot nem kell megőrizni.

static void ShowConfidentialBatchHandling()
{
    object[] incomingRequests = [new BillingQuestion(), new ConfidentialRequest()];
    bool requiresConfidentialHandling =
        ContainsRequestOfType<ConfidentialRequest>(incomingRequests);

    Console.WriteLine(requiresConfidentialHandling
        ? "Send the entire batch to confidential handling."
        : "Send the batch to standard handling.");
}

static bool ContainsRequestOfType<TRequest>(IEnumerable<object> requests)
{
    foreach (object request in requests)
    {
        if (request is TRequest)
        {
            return true;
        }
    }

    return false;
}

Ha a hívónak szüksége van magára az egyező kérelemre, akkor az egyező elemeket visszaadó keresési vagy szűrési művelet megfelelőbb lenne.

Lásd még