Грешка в инструмента за достъп на елементи от масив в C#

Имам два масива в моя клас и се опитвам да получа достъп до тях по следния начин. Първият работи за theta, но вторият не успя да компилира за 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 и нагоре.)

Вместо това ще трябва да изложите свойство от някакъв тип, което само излага съответния индексатор. Сега, ако искате get и set, можете просто да изложите масива като свойство само за четене, евентуално като 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 ли е? Компилаторът съобщава за грешка в Array:delta_theta - person Yang; 26.01.2013
comment
@Yang, не... просто лош избор на име от моя страна - актуализиран... все още не съм се опитал да компилирам... И имаш отговора от Jon - така че е безопасно да пренебрегнеш това :). - person Alexei Levenkov; 26.01.2013