Аксессор элементов массива в ошибке C#

У меня есть два массива в моем классе, и я пытаюсь получить к ним доступ следующим образом. Первый работает для теты, а второй не скомпилировался для delta_theta. Как правильно сделать второй массив без использования этого?

Ошибка гласит: Ошибка 1 Неверный декларатор массива: для объявления управляемого массива спецификатор ранга предшествует идентификатору переменной. Чтобы объявить буферное поле фиксированного размера, используйте ключевое слово fixed перед типом поля.

protected double[] theta = null;
protected double[] delta_theta = null;
public double this[int index] {
        get { return theta[index]; }
        set { theta[index] = value; }
}
public double Delta_Theta[int index]
{
        get { return delta_theta[index]; }
        set { delta_theta[index] = value; }
}

person Yang    schedule 25.01.2013    source источник
comment
Не могли бы вы предоставить нам, какую ошибку выдает компилятор?   -  person igarcia    schedule 26.01.2013


Ответы (3)


Вы не можете указать имя для индексатора в простом коде C#, а также вы не можете создать несколько индексаторов с одинаковыми типами параметров и различать их по имени.

Вы можете указать имя для других языков (которые поддерживают именованные индексаторы) для использования через DefaultMemberAttribute, но вы не можете использовать это имя самостоятельно. (Кроме компонентов COM, а затем только в C# 4 и выше.)

Вместо этого вам нужно предоставить свойство некоторого типа, которое само предоставляет доступ к соответствующему индексатору. Теперь, если вы хотите получить и установить, вы можете просто предоставить массив как свойство только для чтения, возможно, как IList<double>:

// Names changed to be more conventional
public IList<double> DeltaTheta
{
    get { return deltaTheta; }
}

Тогда клиенты все еще могут использовать:

foo.DeltaTheta[10] = 5.5;

Например.

Для версии только для чтения вы можете открыть ReadOnlyCollection<double>:

public ReadOnlyCollection<double> DeltaTheta
{
    get { return new ReadOnlyCollection<double>(deltaTheta); }
}

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

person Jon Skeet    schedule 25.01.2013
comment
Каким тогда будет правильный способ установить и получить значение для каждого отдельного элемента в delta_theta? - person Yang; 26.01.2013

Вы можете создать индексатор-оболочку:

protected double[] theta = null;
protected double[] delta_theta = null;

public double this[int index] {
        get { return theta[index]; }
        set { theta[index] = value; }
}

public Indexer DeltaTheta { 
      // can be optimized according to delta_theta lifecycle
      get {return new Indexer(delta_theta);} 
}

// internal indexere wrapper
public class Indexer{
      double [] _data;
      public DoubleIndexer(double[] data ){   
          _data = data;
      }

      public double this[int index] {
            get { return _data[index]; }
            set { _data[index] = value; }
      }
}

и используйте так:

obj[2]               // -> theta[2]
obj.DeltaTheta[5]    // -> delta_theta[5]
person mdn    schedule 25.01.2013

Невозможно сделать это в одном и том же классе - индексатор должен быть в форме this(arguments), поэтому у вас не может быть 2, которые используют один и тот же тип индекса.

Что вы можете сделать, так это создать внутренний класс с единственной целью, чтобы перенаправить индексацию в ваш массив и заставить Delta_Theta вернуть этот класс.

public IndexRedirector Delta_Theta 
{ 
  get { return new IndexRedirector { RedirectedArray:delta_theta }; 
}

class IndexRedirector
{ 
  public double[] RedirectedArray;
  public double this[int index] {
    get { return RedirectedArray[index]; }
    set { RedirectedArray[index] = value; }
  }
}
person Alexei Levenkov    schedule 25.01.2013
comment
Это новая функция в .net 4? Компилятор сообщает об ошибке в массиве: delta_theta - person Yang; 26.01.2013
comment
@ Ян, нет ... просто неудачный выбор имени с моей стороны - обновлено ... до сих пор не пытался скомпилировать ... И у вас есть ответ от Джона - так что смело его игнорируйте :). - person Alexei Levenkov; 26.01.2013