Я строю структуру данных на основе дерева и перегружен [], чтобы я мог сказать
node["key1", "key2", "key3"]
который возвращает node, чьи родители 1, 2 и 3 уровня выше, являются узлами с этими ключами. узлы концептуально отображают массив данных, поэтому теперь у меня есть эта функция:
node[keys...].SetValue(i, value)
который устанавливает i-е значение в данных node. что было бы неплохо, если бы я мог это сделать:
node[keys][i] = value
проблема заключается в том, что node [keys] возвращает node, поэтому индексирование [i] пытается попасть в другой node. в основном, что я хочу сделать, это перегрузка "[] []" как оператор, которого я не могу.
Есть ли способ получить то, что я пытаюсь сделать?
Примечание: В этом ответе говорится о реализации чего-то типа obj[a][b][c]...
, который может работать с переменным числом скобок. Кажется, это не совсем то, что хотел OP.
Вы не можете перегружать это напрямую. Вы должны вернуть объект с индексом из первого индексатора, чтобы вы могли имитировать эту функциональность.
Это немного сложнее моделировать set
, но можно сделать что-то вроде:
public class Node<T> {
public Node<T> this[string key] {
get { return GetChildNode(key); }
set {
if (value is DummyNode<T>) {
GetChildNode(key).Value = value.Value;
} else {
// do something, ignore, throw exception, depending on the problem
}
}
}
public static implicit operator T(Node<T> value) {
return value.Value;
}
private class DummyNode<T> : Node<T> {
}
public static implicit operator Node<T>(T value) {
return new DummyNode<T> { Value = value };
}
public T Value { get; set; }
}
Кажется, мне просто нужно немного поработать, чтобы понять это... Я создал вторую перегрузку:
public object this[int index]
{
set { ... }
}
который теперь позволяет мне делать
node["child1", "child1 child1"][i] = value
:)
var pat = new Tree<string[]>();
pat["test", "test2", "test3"] = new[] { "test3" };
Console.WriteLine(pat["test", "test2", "test3"][0]);
Волшебные классы - это весело...
public class Tree<T>
{
private Dictionary<string, T> _store = new Dictionary<string, T>();
private string GetKey(string[] index)
{
if (index == null || index.Length == 0) return string.Empty;
return string.Join(".", index);
}
public T this[params string[] index]
{
get
{
var key = GetKey(index);
if (!_store.ContainsKey(key))
return default(T);
return _store[key];
}
set
{
var key = GetKey(index);
if (_store.ContainsKey(key))
_store.Remove(key);
if (value != null)
_store.Add(key, value);
}
}
}