4

考虑一类嵌套数组,每个元素可以是数组或数字:

[[1, 2, [3, 4, [5]], [6, 7]], 8]

这是我为它实现 [] 运算符的尝试。

class MyArray {

    List<MyArray> elements;
    int value;

    public object this[int index] {
        get {
            if (elements.Count > 0) {
                return elements;
            } else {
                return value;
            }
        }
    }

}

所以,我们的目标是像下面这样使用它:

MyArray arr = new MyArray();

... do something with the array here ...

int num = arr[3][5][1];

如果访问“分支”,而不是“叶子”(例如,arr[3][5][1] 有多个元素),让我们只返回 0、无穷大或任何适合我们的整数。

但是,显然,这种嵌套运算符不适用于我的情况,因为运算符的结果是一个对象,而不是 MyArray 实例。

现在,我看到了唯一的解决方案:将转换运算符定义为 int 并使 [] 运算符始终只返回一个元素(如果我们在这里没有遇到异常,它将是 MyArray)。但是有没有别的办法?也许,使用类似 IList 接口的东西会有所帮助吗?或者也许有一种方法可以以某种方式为一个方法定义多种可能的返回类型?(但到目前为止,我用谷歌搜索这是不可能的,并且 C# 中没有 Either 类型)

4

2 回答 2

4

您的运营商应该返回MyArray. 此外,您应该实现MyArrayto的隐式转换运算符int

class MyArray {

    List<MyArray> elements;
    int value;

    public MyArray this[int index] {
        get {
            return elements[index];
        }
    }
    public static implicit operator int(MyArray d) {
        return d.value;
    }
}

问题是 的结构MyArray不是同质的:编译器无法知道它将从[]运算符中得到什么,但您必须指定确切的类型。

一种替代方法是dynamic在返回中使用,但它的使用会带来显着的性能损失。

于 2012-11-29T15:55:53.573 回答
0

您所代表的是一种逻辑“树”类型的数据结构,您只想使用索引器来访问元素(这很好,如果您倾向于在编译时知道树的结构)。

通常对于基于树的数据结构,复合模式是适用的。您有一个定义节点的接口,然后是实现它的两种类型的类;一个用于叶子,一个用于父节点。然后节点接口有一些(或集合)其他节点(可以是实现,或者如果它是叶节点,它可以是空集合)。

这是一个不使用接口的更简单的实现;它不是那么健壮(它更多地依赖于约定来告诉你发生了什么),但概念是一样的:

public class Node
{
    private List<Node> children = new List<Node>();

    /// <summary>
    /// This will have a non-null value if it's a leaf.  It will be null if it's not a leaf.
    /// </summary>
    public int? Value { get; set; } 

    public Node this[int index]
    {
        get
        {
            if (children.Count == 0)
            {
                throw new ArgumentException("This node has no children");
            }
            if (children.Count > index)
            {
                throw new ArgumentException("This node doesn't have that many children");
            }

            return children[index];
        }
    }
}
于 2012-11-29T16:21:37.927 回答