Programování

Jak pracovat s indexery v C #

Programovací jazyk C # zahrnuje podporu indexerů - funkce, která umožňuje použít objekt stejně jako pole. Indexery jsou také známé jako inteligentní pole a lze je definovat podobně, jak je definována vlastnost. MSDN uvádí: "Indexery umožňují, aby instance třídy nebo struktury byly indexovány stejně jako pole. Indexery připomínají vlastnosti kromě toho, že jejich přístupoví uživatelé berou parametry."

Ačkoli indexery a vlastnosti mají podobnosti ve více než jednom, existují mezi nimi jemné rozdíly. Na rozdíl od vlastností můžete přistupovat k indexeru pomocí indexů. Nezapomeňte, že k vlastnosti musíte přistupovat pomocí jejího názvu. Indexery jsou také členy instance třídy, a proto nemohou být statické. Můžete mít statické i nestatické vlastnosti.

Následující fragment kódu ukazuje, jak je deklarován indexátor:

tento [seznam argumentů]

{

dostat

  {

  }

Soubor

  {

  }

}

Všimněte si, že modifikátor zobrazený v deklaraci syntaxe indexeru může být soukromý, veřejný, chráněný nebo interní.

Zvažte následující třídu:

veřejná třída Kontakt

    {

soukromý řetězec [] adresa = nový řetězec [3];

veřejný řetězec tento [int index]

        {

dostat

            {

zpáteční adresa [index];

            }

soubor

            {

adresa [index] = hodnota;

            }

        }

    }

Třída Contact obsahuje soukromého člena s názvem adresa a definuje indexer. Člen adresy je pole typového řetězce. Tady je příklad, jak můžete vytvořit instanci třídy Contact a použít indexer.

Kontaktní kontakt = nový Kontakt ();

kontakt [0] = "Begumpet";

kontakt [1] = "Hyderabad";

kontakt [2] = "Telengana";

pro (int i = 0; i <3; i ++)

Console.WriteLine (kontakt [i]);

Je třeba poznamenat, že k definování indexerů musíte použít klíčové slovo „this“. Všimněte si, že nejste omezeni na používání pouze celých čísel jako indexů pro přístup k indexátorům - můžete dokonce použít i jiné vyhledávací mechanismy. Indexer se obvykle používá, když vaše třída představuje kolekci nebo objekty. Potom můžete použít indexer pro přístup ke konkrétnímu prvku pomocí indexu.

Zkusme příklad. Zvažte následující třídu s názvem Zákazník.

veřejná třída Zákazník

    {

veřejné seznamy objednávek

        {

dostat; soubor;

        }

public Objednat toto [int ID_objednávky]

        {

dostat

            {

návrat (od o v objednávkách

kde o.OrderID == IDObjednávky

vyberte o). First ();

            }

        }

    }

Třída Customer definuje indexer typu Order. Obsahuje také veřejnou vlastnost, která je seznamem typu Order. Tady je třída Order pro vaši referenci.

veřejná třída Objednávka

    {

public int OrderID

        {

dostat; soubor;

        }

    }

Následující fragment kódu ukazuje, jak můžete získat přístup k indexeru třídy Customer k načtení konkrétní objednávky.

   List lstOrder = nový List ();

Objednávka o1 = nová objednávka ();

o1.OrderID = 1;

Objednávka o2 = nová objednávka ();

o2.OrderID = 2;

lstOrder.Add (o1);

lstOrder.Add (o2);

Zákazník zákazník = nový zákazník ();

customer.Orders = lstOrder;

Objednávka o = zákazník [1];

Viz výše uvedený fragment kódu. Všimněte si, jak byl vytvořen obecný seznam typu Order a přiřazen k vlastnosti Orders instance třídy Customer. Dále stačí předat OrderId jako parametr k načtení konkrétní instance objednávky.

Indexery podporují dědičnost, mohou být polymorfní a mohou být také abstraktní. Zvažte následující třídu, která definuje indexer, který je virtuální. Třída ContactBase je upravená verze třídy Kontakt, o které jsme hovořili dříve v tomto článku.

veřejná třída ContactBase

    {

chráněný řetězec [] adresa = nový řetězec [3];

veřejný virtuální řetězec tento [int index]

        {

dostat

            {

zpáteční adresa [index];

            }

soubor

            {

adresa [index] = hodnota;

            }

        }

    }

Nyní můžete odvodit třídu z ContactBase třídy a přepsat indexer, jak je znázorněno níže.

veřejná třída ConcreteContact: ContactBase

    {

public override string this [int index]

        {

dostat

            {

zpáteční adresa [index];

            }

soubor

            {

adresa [index] = hodnota;

            }

        }

    }

V příkladu kódu výše jsme tedy prozkoumali, jak lze indexery použít při dědění typů a jak mohou ukázat polymorfní chování.

Můžete stejně dobře definovat indexer jako abstraktní. Chcete-li to provést, musíte vytvořit abstraktní třídu a poté v ní definovat indexer jako abstraktní. Pojďme upravit ContactBase třídu a definovat indexer jako abstraktní. Zde bude vypadat upravená verze třídy ContactBase:

 veřejná abstraktní třída ContactBase

    {

chráněný řetězec [] adresa = nový řetězec [3];

veřejný abstraktní řetězec tento [int index]

        {

dostat; soubor;

        }

}

Třídu ConcreteContact stejně nemusíte měnit. Nyní můžete využít indexer k přiřazení řetězcových hodnot instanci třídy ConcreteContact třídy, jak je znázorněno níže.

ConcreteContact kontakt = nový ConcreteContact ();

kontakt [0] = "Begumpet";

kontakt [1] = "Hyderabad";

kontakt [2] = "Telengana";

$config[zx-auto] not found$config[zx-overlay] not found