Инициализация класса с индексатором

292
07 апреля 2017, 20:37

Задали вопрос на собеседовании. Возможно ли инициализировать экземпляр класса с индексатором блоком инициализатора?

class MyClass
{
    private int[] array = new int[5];
    public int this[int index]
    {
        get
        {
            return array[index];
        }
        set
        {
            array[index] = value;
        }
    }
}
class Program
{
    static void Main()
    {
        // Допустима ли чисто теоретически такая инициализация?
        MyClass my = new MyClass(){1,2,3,4,5};
        //my[0] = 1;
        //my[1] = 2;
        //my[2] = 3;
        //my[3] = 4;
        //my[4] = 5;
        Console.ReadKey();
    }
}

Если реализовать два интерфейса iEnumerable и IEnumerator:

class MyClass : IEnumerable, IEnumerator
{
    private int[] array = new int[5];
    int index;
    // Индексатор. 
    public int this[int index]
    {
        get    // Аксессор.
        {
            return array[index];
        }
        set    // Мутатор.
        {
            array[index] = value;
        }
    }
    public IEnumerator GetEnumerator()
    {
        return this;
    }
    public bool MoveNext()
    {
        if(index == array.Length - 1)
        {
            Reset();
            return false;
        }
        index++;
        return true;
    }
    public void Reset()
    {
        index = -1;
    }
    public object Current
    {
        get
        {
            return array[index];
        }
    }
}

В блоке инициализатора VS на каждое число ругается:

CS1061 'MyClass' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type 'MyClass' could be found (are you missing a using directive or an assembly reference?

Как можно реализовать метод Add в классе, чтобы конструкция инициализатора работала? Или же это недопустимо?

Answer 1

Если не нужно использовать foreach loop, а нужна только инициализация значений блоком инициализатора, то достаточно просто унаследоваться от IEnumerable, по сути не реализуя сам метод GetEnumerator() и добавить метод Add():

public class MyClass : IEnumerable
{
    private List<int> array = new List<int>();
    public int this[int index]
    {
        get
        {
            return array[index];
        }
        set
        {
            array[index] = value;
        }
    }
    public IEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }
    public void Add(int value)
    {
        this.array.Add(value);
    }
}

Такой класс можно инициализировать следующим образом:

MyClass instance = new MyClass { 1, 2, 6, 7, 8, 9, 10 }
READ ALSO
Как в wfa приложении С# выполнить SQL скрипт?

Как в wfa приложении С# выполнить SQL скрипт?

C простыми SQL запросами всё понятно,

387
Какая разница между System.Security.SecurityException и System.UnauthorizedAccessException?

Какая разница между System.Security.SecurityException и System.UnauthorizedAccessException?

Конструктор FileInfo выбрасывает оба вышеуказанных исключенияПланируется использовать FileInfo для определения корректности пути по аналогии...

328
Как получить число типа float из двух байт?

Как получить число типа float из двух байт?

Как получить число типа float из двух байт? Есть два байтаДопустим 0x02 - младшая часть и 0x04 - старшая часть

251