Технически это не правильный способ использования StackOverflow, но я посчитал вашу идею настолько полезной, что расширил ее. Я думал, что это сэкономит людям время, если я опубликую то, что я придумал, и пример того, как его использовать.
Во-первых, мне нужно было иметь возможность поддерживать свойства только для получения и только для набора, поэтому я немного изменил ваш код для этих сценариев:
Получить и установить (очень незначительные изменения):
public class IndexedProperty<TIndex, TValue>
{
readonly Action<TIndex, TValue> SetAction;
readonly Func<TIndex, TValue> GetFunc;
public IndexedProperty(Func<TIndex, TValue> getFunc, Action<TIndex, TValue> setAction)
{
this.GetFunc = getFunc;
this.SetAction = setAction;
}
public TValue this[TIndex i]
{
get
{
return GetFunc(i);
}
set
{
SetAction(i, value);
}
}
}
Get Only:
public class ReadOnlyIndexedProperty<TIndex, TValue>
{
readonly Func<TIndex, TValue> GetFunc;
public ReadOnlyIndexedProperty(Func<TIndex, TValue> getFunc)
{
this.GetFunc = getFunc;
}
public TValue this[TIndex i]
{
get
{
return GetFunc(i);
}
}
}
Установить только:
public class WriteOnlyIndexedProperty<TIndex, TValue>
{
readonly Action<TIndex, TValue> SetAction;
public WriteOnlyIndexedProperty(Action<TIndex, TValue> setAction)
{
this.SetAction = setAction;
}
public TValue this[TIndex i]
{
set
{
SetAction(i, value);
}
}
}
Пример * ** тысяча двадцать-один * тысяча двадцать два
Вот простой пример использования. Я наследую от Collection и создаю именованный индексатор, как его назвал Джон Скит. Этот пример должен быть простым, а не практичным:
public class ExampleCollection<T> : Collection<T>
{
public IndexedProperty<int, T> ExampleProperty
{
get
{
return new IndexedProperty<int, T>(GetIndex, SetIndex);
}
}
private T GetIndex(int index)
{
return this[index];
}
private void SetIndex(int index, T value)
{
this[index] = value;
}
}
ExampleCollection in the Wild
Этот наспех построенный модульный тест показывает, как он выглядит, когда вы ExampleCollection в проекте:
[TestClass]
public class IndexPropertyTests
{
[TestMethod]
public void IndexPropertyTest()
{
var MyExample = new ExampleCollection<string>();
MyExample.Add("a");
MyExample.Add("b");
Assert.IsTrue(MyExample.ExampleProperty[0] == "a");
Assert.IsTrue(MyExample.ExampleProperty[1] == "b");
MyExample.ExampleProperty[0] = "c";
Assert.IsTrue(MyExample.ExampleProperty[0] == "c");
}
}
Наконец, если вы хотите использовать версии только для получения и для установки, это выглядит так:
public ReadOnlyIndexedProperty<int, T> ExampleProperty
{
get
{
return new ReadOnlyIndexedProperty<int, T>(GetIndex);
}
}
Или:
public WriteOnlyIndexedProperty<int, T> ExampleProperty
{
get
{
return new WriteOnlyIndexedProperty<int, T>(SetIndex);
}
}
В обоих случаях результат работает точно так, как вы ожидаете, что будет работать только свойство get-only / set-only.