在c#中重载[][]

发布于 2024-07-25 09:24:15 字数 418 浏览 7 评论 0原文

我正在构建一个基于树的数据结构并重载 [ ],以便我可以说它

node["key1", "key2", "key3"]

返回其父级 1、2 和 3 级以上的节点是具有这些键的节点。 节点在概念上映射到数据数组,所以我现在拥有的是这个函数:

node[keys...].SetValue(i, value)

它设置节点数据中的第 i 个值。 如果我能这样做就好了:

node[keys][i] = value

问题是,node[keys] 返回一个节点,因此 [i] 索引尝试获取另一个节点。 基本上我想要做的是将“[][]”重载为运算符,但我做不到。

有什么办法可以实现我想做的事情吗?

I'm building a tree-based data structure and overloaded [ ] so that I can say

node["key1", "key2", "key3"]

which returns the node whose parents 1, 2, and 3 levels above are the nodes with those keys. the nodes conceptually map to an array of data, so what I have now is this function:

node[keys...].SetValue(i, value)

which sets the i-th value in the node's data. what would be nice is if I could do this:

node[keys][i] = value

problem is, node[keys] returns a node, so the [i] indexing tries to get at another node. basically what I want to be able to do is overload "[ ][ ]" as an operator, which I can't.

is there any way to get at what I'm trying to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

森林很绿却致人迷途 2024-08-01 09:24:15

注意:这个答案讨论了实现类似 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; }
}

Note: This answer talks about implementing something like obj[a][b][c]... that could work with variable number of brackets. It seems it's not exactly what the OP wanted.

You can't overload that directly. You should return an object with an indexer from the first indexer so that you could simulate this functionality.
It's a bit harder to simulate set but it's possible to do something like:

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; }
}
榕城若虚 2024-08-01 09:24:15

看来我只需要多做一些修改来弄清楚...我创建了第二个重载:

public object this[int index]
{
    set { ... }
}

现在让我可以这样做

node["child1", "child1's child1"][i] = value

:)

seems I just needed to tinker a bit more to figure it out...I created a second overload:

public object this[int index]
{
    set { ... }
}

which now lets me do

node["child1", "child1's child1"][i] = value

:)

眼眸印温柔 2024-08-01 09:24:15
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);
        }
    }
}
var pat = new Tree<string[]>();
pat["test", "test2", "test3"] = new[] { "test3" };
Console.WriteLine(pat["test", "test2", "test3"][0]);

Magic classes are fun...

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);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文