В С# я считаю проиндексированные свойства чрезвычайно полезными. Например:
var myObj = new MyClass();
myObj[42] = "hello";
Console.WriteLine(myObj[42]);
Однако, насколько я знаю, нет синтаксического сахара для поддержки полей, которые сами поддерживают индексацию (пожалуйста, исправьте меня, если я ошибаюсь). Например:
var myObj = new MyClass();
myObj.field[42] = "hello";
Console.WriteLine(myObj.field[42]);
Причина, по которой мне это нужно, заключается в том, что я уже использую свойство index в своем классе, но у меня есть функции GetNumX()
, GetX()
и SetX()
следующим образом:
public int NumTargetSlots {
get { return _Maker.NumRefs; }
}
public ReferenceTarget GetTarget(int n) {
return ReferenceTarget.Create(_Maker.GetReference(n));
}
public void SetTarget(int n, ReferenceTarget rt) {
_Maker.ReplaceReference(n, rt._Target, true);
}
Как вы, вероятно, видите, экспонирование их как одного индексируемого свойства поля имело бы больше смысла. Я мог бы написать собственный класс, чтобы достичь этого каждый раз, когда я хочу синтаксический сахар, но весь стандартный код просто кажется ненужным.
Поэтому я написал собственный класс для инкапсуляции шаблона и облегчения создания свойств, которые можно проиндексировать. Таким образом, я могу добавить новое свойство следующим образом:
public IndexedProperty<ReferenceTarget> TargetArray {
get {
return new IndexedProperty<int, ReferenceTarget>(
(int n) => GetTarget(n),
(int n, ReferenceTarget rt) => SetTarget(n, rt));
}
}
Код для этого нового класса IndexedProperty выглядит следующим образом:
public class IndexedProperty<IndexT, ValueT>
{
Action<IndexT, ValueT> setAction;
Func<IndexT, ValueT> getFunc;
public IndexedProperty(Func<IndexT, ValueT> getFunc, Action<IndexT, ValueT> setAction)
{
this.getFunc = getFunc;
this.setAction = setAction;
}
public ValueT this[IndexT i]
{
get {
return getFunc(i);
}
set {
setAction(i, value);
}
}
}
Итак, мой вопрос: есть ли лучший способ сделать все это?
Если говорить точнее, есть ли в С# более идиоматический способ создания свойства индексируемого поля, и если нет, то как я могу улучшить свой класс IndexedProperty
?
ОБНОВЛЕНИЕ: После дальнейшего исследования Джон Скит называет это "именованным индексатором".