Подтвердить что ты не робот

Случаи использования в реальном мире для индексаторов С#?

Я видел множество примеров для индексов С#, но каким образом это поможет мне в реальных ситуациях.

Я знаю, что гуру С# не добавили бы это, если бы это была не серьезная функция, но я не могу думать о ситуации в реальном мире (а не о фьюзерах) для использования индексаторов.

Примечание. Я понимаю вопрос , но мне это не очень помогает.

4b9b3361

Ответ 1

То, как я смотрю на индексаторы, это то, что (правильно или неправильно!), доступ к чему-то по индексу должен быть более эффективным, чем доступ к нему любым другим способом, потому что в некотором роде форма или форма, класс, чей индекс я использую хранит некоторую форму индекса, которая позволяет ему быстро искать значения при обращении к этому пути.

Классический пример - это массив, когда вы обращаетесь к элементу n массива с помощью кода myarray [3], компилятор/интерпретатор знает, насколько велики (по памяти) элементы массива и могут рассматривать его как смещение от начала массива. Вы могли бы также "for(int i = 0; i < myarray.length; i++) { if (i = 3) then { .. do stuff } }" (не то, чтобы вы когда-либо захотели!), Что было бы менее эффективно. Он также показывает, как массив является плохим примером.

Скажем, у вас был класс коллекции, в котором хранятся, ммм, DVD-диски, поэтому:

public class DVDCollection
{
    private Dictionary<string, DVD> store = null;
    private Dictionary<ProductId, string> dvdsByProductId = null;

    public DVDCollection()
    {
        // gets DVD data from somewhere and stores it *by* TITLE in "store"
        // stores a lookup set of DVD ProductId and names in "dvdsByProductid"
        store = new Dictionary<string, DVD>();
        dvdsByProductId = new Dictionary<ProductId, string>();
    }

    // Get the DVD concerned, using an index, by product Id
    public DVD this[ProductId index]  
    {
       var title = dvdsByProductId[index];
       return store[title];
    }
}

Просто мой 2p, но, как я уже сказал, я всегда считал "индексатора" целесообразным способом получения данных из чего-то.

Ответ 2

Наиболее очевидными примерами, упомянутыми Скурмелем, являются List<T> и Dictionary<TKey, TValue>. Что бы вы предпочли:

List<string> list = new List<string> { "a", "b", "c" };
string value = list[1]; // This is using an indexer

Dictionary<string, string> dictionary = new Dictionary<string, string>
{
    { "foo", "bar" },
    { "x", "y" }
};
string value = dictionary["x"]; // This is using an indexer

? Теперь это может быть относительно редко, потому что вам нужно написать индексатор (обычно, когда вы создаете класс, подобный коллекции), но я подозреваю, что вы используете их достаточно часто.

Ответ 3

Microsoft имеет пример с помощью индексатора для обработки файла в виде массива байтов.

public byte this[long index]
{
    // Read one byte at offset index and return it.
    get 
    {
        byte[] buffer = new byte[1];
        stream.Seek(index, SeekOrigin.Begin);
        stream.Read(buffer, 0, 1);
        return buffer[0];
    }
    // Write one byte at offset index and return it.
    set 
    {
        byte[] buffer = new byte[1] {value};
        stream.Seek(index, SeekOrigin.Begin);
        stream.Write(buffer, 0, 1);
    }
}

Ответ 4

Скажем, у вас есть коллекция объектов, которые вы хотите иметь возможность индексировать чем-то иным, чем порядок, в котором она была помещена в коллекцию. В приведенном ниже примере вы можете увидеть, как вы можете использовать свойство "Местоположение" для какого-либо объекта и с помощью индексатора, вернуть все объекты в коллекции, которые соответствуют вашему местоположению, или во втором примере все объекты, содержащие определенный граф ( ) объектов.

class MyCollection {

  public IEnumerable<MyObject> this[string indexer] {
    get{ return this.Where(p => p.Location == indexer); }
  }

  public IEnumerable<MyObject> this[int size] {
    get{ return this.Where(p => p.Count() == size);}
  }
}

Ответ 5

Как только .NET получил дженерики, самая большая причина для меня реализовать индексатор (для реализации сильно типизированной коллекции) ушла.

Ответ 6

Это синтаксический сахар для классов типа коллекции. У меня никогда не было причины писать такой класс. Поэтому я думаю, что это очень редкое использование в "реальной жизни", потому что классы, использующие его, уже реализованы.

Ответ 7

В ASP.Net существует несколько раз, когда используется индекс, например, чтение чего-либо из любого объекта запроса, сеанса или приложения. Я часто видел, что что-то хранится в объекте Session или Application только для использования снова и снова.

Ответ 8

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IndexerSample
{
    class FailSoftArray 
    {
        int[] a; // reference to underlying array
        public int Length; // Length is public
        public bool ErrFlag; // indicates outcome of last operation
        // Construct array given its size.
        public FailSoftArray(int size)
        {
            a = new int[size];
            Length = size;
        }
        // This is the indexer for FailSoftArray.
        public int this[int index] 
        {
        // This is the get accessor.
            get
            {
                if (ok(index))
                {
                    ErrFlag = false;
                    return a[index];
                }
                else
                {
                    ErrFlag = true;
                    return 0;
                }
            }
            // This is the set accessor.
            set
            {
                if (ok(index))
                {
                    a[index] = value;
                    ErrFlag = false;
                }
                else ErrFlag = true;
            }
        }
        // Return true if index is within bounds.
        private bool ok(int index)
        {
            if (index >= 0 & index < Length) return true;
            return false;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            FailSoftArray fs = new FailSoftArray(5);
            int x;
            // Show quiet failures.
            Console.WriteLine("Fail quietly.");
            for (int i = 0; i < (fs.Length * 2); i++)
                fs[i] = i * 10;
            for (int i = 0; i < (fs.Length * 2); i++)
            {
                x = fs[i];
                if (x != -1) Console.Write(x + " ");
            }
            Console.WriteLine();
            // Now, display failures.
            Console.WriteLine("\nFail with error reports.");
            for (int i = 0; i < (fs.Length * 2); i++)
            {
                fs[i] = i * 10;
                if (fs.ErrFlag)
                    Console.WriteLine("fs[" + i + "] out-of-bounds");
            }
            for (int i = 0; i < (fs.Length * 2); i++)
            {
                x = fs[i];
                if (!fs.ErrFlag) Console.Write(x + " ");
                else
                    Console.WriteLine("fs[" + i + "] out-of-bounds");
            }
            Console.ReadLine();
        }
    }
}

Ответ 9

http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html

Индексаторы - это элементы в программе на С#, которые позволяют классу вести себя как массив. Вы могли бы использовать весь класс как массив. В этом массиве вы можете хранить любые типы переменных. Переменные хранятся в отдельном месте, но адресуются самим именем класса. Создание индексаторов для целых чисел, строк, булевых и т.д. Было бы осуществимой идеей. Эти индексаторы эффективно действовали бы на объектах класса.

Предположим, вы создали индексатор классов, в котором хранится номер рулона ученика в классе. Кроме того, предположим, что вы создали объект этого класса с именем obj1. Когда вы говорите obj1 [0], вы имеете в виду первого ученика в броске. Аналогично, obj1 [1] относится к 2-му ученику в броске.

Поэтому объект принимает индексированные значения для ссылки на переменную Integer, которая конфиденциально или публично хранится в классе. Предположим, что у вас не было этого объекта, тогда вы, вероятно, ссылаетесь таким образом (что будет длиннее):

obj1.RollNumberVariable[0]
obj1.RollNumberVariable[1]. 

где RollNumberVariable будет переменной Integer, которая ссылается на номер рулона текущего объекта студента.

Подробнее http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html

Ответ 10

Вот видео, которое я создал http://www.youtube.com/watch?v=HdtEQqu0yOY, а ниже - подробное объяснение о том же.

Индексаторы помогают получить доступ к содержащейся коллекции в классе с использованием упрощенного интерфейса. Его синтаксический сахар.

Например, скажем, у вас есть класс клиентов с коллекцией адресов внутри него. Теперь позвольте сказать, что мы хотели бы получить выборку из коллекции "Pincode" и "PhoneNumber". Таким образом, логичным шагом будет то, что вы идете и создаете две перегруженные функции, которые выбираются с помощью "PhoneNumber", а другой - "PinCode". Вы можете видеть в приведенном ниже коде, у нас есть две функции.

Customer Customers = new Customer();
Customers.getAddress(1001);
Customers.getAddress("9090");

Если вы используете индексатор, вы можете упростить приведенный выше код, как показано в приведенном ниже коде.

Customer Customers = new Customer();
Address o = Customers[10001];
o = Customers["4320948"];

Приветствия.

Ответ 11

http://code-kings.blogspot.in/2012/09/indexers-in-c-5.html

с помощью System;

namespace Indexers_Example

{

class Indexers
{

    private Int16[] RollNumberVariable;

    public Indexers(Int16 size)
    {
        RollNumberVariable = new Int16[size];

        for (int i = 0; i < size; i++)
        {
            RollNumberVariable[i] = 0;
        }
    }

    public Int16 this[int pos]
    {
        get
        {
            return RollNumberVariable[pos];
        }
        set
        {
            RollNumberVariable[pos] = value;
        }
    }
}

}

Ответ 12

Дополнение к сообщению @code-kings.

Кроме того, вызов RollNumberVariable[0] вызывает поведение индексатора коллекции по умолчанию. Хотя индексы на самом деле свойства, от вашего имени нужно писать свою собственную логику при извлечении данных. Вы можете легко делегировать большую часть значения параметра индекса во внутреннюю коллекцию, но вы также можете вернуть любое произвольное значение для определенных значений индекса.

Просто пример - у вас могут быть 2+ внутренние коллекции в другом формате, но внешний пользователь будет взаимодействовать с ними через один индекс (который будет работать как диспетчер) в то время как эта коллекция будет скрыта. Это в значительной степени поощряет принцип инкапсуляции.

Ответ 13

Я пытаюсь получить изображения из файла последовательности. Мне нужен какой-то 2D-массив или зубчатый массив для хранения значений пикселей. Я использую индексы вместо массивов, потому что цикл по индексам быстрее, чем цикл по 2D или зубчатым массивам.

Ответ 14

Вы можете использовать индексатор для элегантного предоставления многопоточной синхронизации чтения/записи в не-потоковом безопасном словаре (или любой небезобезопасной коллекции):

internal class ThreadSafeIndexerClass
{
    public object this[int key]
    {
        get
        {
            // Aquire returns IDisposable and does Enter() Exit() on a certain ReaderWriterLockSlim instance
            using (_readLock.Aquire()) 
            {
                object subset;
                _dictionary.TryGetValue(key, out foundValue);
                return foundValue;
            }
        }
        set
        {
            // Aquire returns IDisposable and does Enter() Exit() on a certain ReaderWriterLockSlim instance
            using (_writeLock.Aquire())
                _dictionary[key] = value;
        }
    }
}

Полезно особенно, когда вы не хотите использовать тяжелый ConcurrentDictionary (или любую другую параллельную коллекцию).