Свойства, отображающие элементы массива в С#
Я хочу создать свойство в С#, которое устанавливает или возвращает отдельный элемент массива. В настоящее время у меня есть это:
private string[] myProperty;
public string MyProperty[int idx]
{
get
{
if (myProperty == null)
myProperty = new String[2];
return myProperty[idx];
}
set
{
myProperty[idx] = value;
}
}
Однако я получаю следующую ошибку компиляции:
Неверный идентификатор массива: для объявления управляемого массива спецификатор рангов предшествует идентификатору переменной. Чтобы объявить поле буфера фиксированного размера, используйте ключевое слово fixed до типа поля.
Ответы
Ответ 1
Как об этом: напишите класс, который делает только одно и только одно: предоставлять произвольный доступ к элементам некоторой базовой индексированной коллекции. Дайте этому классу индекс this
.
Для свойств, которые вы хотите предоставить произвольный доступ, просто верните экземпляр этого класса индексатора.
Тривиальная реализация:
public class Indexer<T>
{
private IList<T> _source;
public Indexer(IList<T> source)
{
_source = source;
}
public T this[int index]
{
get { return _source[index]; }
set { _source[index] = value; }
}
}
public static class IndexHelper
{
public static Indexer<T> GetIndexer<T>(this IList<T> indexedCollection)
{
// could cache this result for a performance improvement,
// if appropriate
return new Indexer<T>(indexedCollection);
}
}
Рефакторинг в ваш код:
private string[] myProperty;
public Indexer<string> MyProperty
{
get
{
return myProperty.GetIndexer();
}
}
Это позволит вам иметь столько индексированных свойств, сколько вам нужно, без необходимости раскрывать эти свойства с помощью интерфейса IList<T>
.
Ответ 2
Вы должны использовать this
как имя свойства для индексаторов.
Ответ 3
С# допускает только одно индексированное свойство для каждого класса, поэтому вы вынуждены использовать это.
Ответ 4
Вы можете использовать его следующим образом:
private string[] myProp;
public string[] MyProp
{
get
{
if (myProp == null)
{
myProp = new String[2];
}
return myProp;
}
set
{
myProp = value;
}
}
И можно использовать myProp [1] как MyProp [1] для примера
Ответ 5
Предоставление вашего массива через свойство только для чтения может удовлетворить ваши потребности. Поскольку вы не хотите, чтобы другой код назначал массив как таковой, нет необходимости в публичном сетевом устройстве:
private string[] myProperty;
public string[] MyProperty
{
get
{
if (myProperty == null)
{
myProperty = new String[2];
}
return myProperty;
}
}
Затем вы можете написать код как таковой:
theObject.MyProperty[1] = "some string";
... но вы не можете заменить сам массив:
theObject.MyProperty = new string[2]; // will not compile
Ответ 6
Опция состоит в том, чтобы перекодировать ее следующим образом:
private string[] myProperty = new string[2];
public string[] MyProperty
{
get
{
return myProperty;
}
set
{
myProperty = value;
}
}
Он будет компилироваться, но у него есть свой собственный набор проблем (fxCop будет кричать об этом, но он может привести вас к другим параметрам).
Ответ 7
Вы можете сделать что-то вроде этого:
class Indexers
{
private string[] _strings = new [] {"A","B"};
private int[] _ints = new[] { 1, 2 };
public string[] Strings
{
get{ return _strings;}
}
public int[] Ints
{
get{ return _ints;}
}
}
class Program
{
static void Main(string[] args)
{
Indexers indexers = new Indexers();
int a1 = indexers.Ints[0];
string a2 = indexers.Strings[0];
}
}
Ответ 8
Во-первых, объявление в полевых условиях позволяет избежать избыточной проверки:
private string[] myProperty = new string[2];
Вы можете реализовать несколько индексов с помощью перегрузки по типу ввода:
public string this[int index]
{
get
{
return myProperty[index];
}
set
{
myProperty[index] = value;
}
}
public object this[object a, object b] // different input type(s) (and different return type)
{
get
{
// do other stuff
}
}
Ответ 9
С# не предоставляет встроенного механизма для создания индексированных свойств. Вы можете использовать индексатор уровня класса (используя нотацию this[int index]
), но ничего подобного на уровне свойства.
Один из вариантов - создать вспомогательный класс с индексом и использовать этот класс в качестве типа свойства. См. пример в MSDN.
Ответ 10
Вам нужно использовать индекс. Он работает по-другому. Пример:
public class Node
{
public Node this[int offset]
{
get { return localList[offset]; }
}
}
Примечание. Допускается только один индекс для каждого класса. Причина в том, что он слишком запутан для компилятора относительно значения, поэтому вам разрешено только одно.
Вы также можете сделать это:
private static int[] _widget = new int[Counter];
public static int [] Widget
{
get { return _widget; }
set { _widget = value; }
}
...
for (int i = 0; i < MyClass.Counter; i++)
{
MyClass.Widget[i] = i;
}
...
double _newWidget5 = MyClass.Widget[5];
// and so on...