Как да работите с индексатори в C #

Езикът за програмиране C # включва поддръжка за индексатори - функция, която ви позволява да използвате обект точно като масив. Индексаторите са известни също като интелигентни масиви и могат да бъдат дефинирани подобно на начина, по който се дефинира свойството. MSDN гласи: "Индексаторите позволяват индекси на клас или структура да бъдат индексирани точно като масиви. Индексаторите приличат на свойства, с изключение на това, че техните достъпи вземат параметри."

Въпреки че индексаторите и свойствата имат прилики по повече от един начин, между тях има фини разлики. За разлика от свойствата, можете да получите достъп до индексатор, използвайки индекси. Не забравяйте, че трябва да получите достъп до свойство, като използвате неговото име. Също така, индексаторите са членове на екземпляр на клас и следователно не могат да бъдат статични. Можете да имате както статични, така и нестатични свойства.

Следният кодов фрагмент илюстрира как се декларира индексатор:

this [argument list]

{

  get

  {

  }

  Set

  {

  }

}

Имайте предвид, че модификаторът, както е показано в декларацията за синтаксис на индексатор, може да бъде частен, публичен, защитен или вътрешен.

Помислете за следния клас:

public class Contact

    {

        private string[] address = new string[3];

        public string this[int index]

        {

            get

            {

                return address[index];

            }

            set

            {

                address[index] = value;

            }

        }

    }

Класът за контакт съдържа частен член с име и дефинира индексатор. Адресният член е масив от тип string. Ето как можете да създадете екземпляр на класа Contact и да използвате индексатора.

Contact contact = new Contact();

 contact[0] = "Begumpet";

 contact[1] = "Hyderabad";

 contact[2] = "Telengana";

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

Console.WriteLine (contact[i]);

Трябва да се отбележи, че трябва да използвате ключовата дума "this", за да дефинирате индексатори. Имайте предвид, че не сте ограничени да използвате само цели числа като индекси за достъп до индексатори - можете дори да използвате и други механизми за търсене. Индексаторът обикновено се използва, когато вашият клас представлява колекция или обекти. След това можете да използвате индексатор за достъп до определен елемент с помощта на index.

Нека опитаме пример. Помислете за следния клас с име Клиент.

public class Customer

    {

       public List Orders

        {

            get; set;

        }

       public Order this[int orderID]

        {

            get

            {

                return (from o in Orders

                        where o.OrderID == orderID

                        select o).First();

            }

        }

    }

Класът клиент дефинира индексатор от тип Поръчка. Той също така съдържа публична собственост, която е списък от тип Order. Ето класа за поръчка за справка.

public class Order

    {

        public int OrderID

        {

            get; set;

        }

    }

Следният кодов фрагмент илюстрира как можете да получите достъп до индексатора на класа Customer, за да извлечете определена поръчка.

   List lstOrder = new List();

  Order o1 = new Order();

  o1.OrderID = 1;

  Order o2 = new Order();

  o2.OrderID = 2;           

  lstOrder.Add(o1);

  lstOrder.Add(o2);

  Customer customer = new Customer();

  customer.Orders = lstOrder;

  Order o = customer[1];

Обърнете се към кодовия фрагмент по-горе. Обърнете внимание как е създаден общ списък от тип Order и е присвоен на свойството Orders на екземпляр от класа Customer. След това просто предавате OrderId като параметър, за да извлечете конкретния екземпляр на поръчка.

Индексаторите поддържат наследяване, могат да бъдат полиморфни и могат да бъдат абстрактни. Да разгледаме следния клас, който дефинира индексатор, който е виртуален. Класът ContactBase е модифицирана версия на класа Contact, който обсъдихме по-рано в тази статия.

 public class ContactBase

    {

        protected string[] address = new string[3];

        public virtual string this[int index]

        {

            get

            {

                return address[index];

            }

            set

            {

                address[index] = value;

            }

        }

    }

Вече можете да извлечете клас от класа ContactBase и да замените индексатора, както е показано по-долу.

public class ConcreteContact: ContactBase

    {

       public override string this[int index]

        {

            get

            {

                return address[index];

            }

            set

            {

                address[index] = value;

            }

        }

    }

И така, в примера с кода по-горе, изследвахме как индексаторите могат да се използват при наследяване на типове и как те могат да показват полиморфно поведение.

Можете също толкова добре да дефинирате индексатора, колкото и абстрактния. За да направите това, трябва да създадете абстрактен клас и след това да дефинирате индексатор като абстрактен в него. Нека модифицираме класа ContactBase и дефинираме индексатора като абстрактен. Ето как би изглеждала сега модифицираната версия на класа ContactBase:

 public abstract class ContactBase

    {

        protected string[] address = new string[3];

        public abstract string this[int index]

        {

            get; set;

        }

}

Не е необходимо да променяте класа ConcreteContact така или иначе. Вече можете да използвате индексатора, за да присвоява низови стойности на екземпляр от класа ConcreteContact, както е показано по-долу.

ConcreteContact contact = new ConcreteContact();

contact[0] = "Begumpet";

contact[1] = "Hyderabad";

contact[2] = "Telengana";