考虑一类嵌套数组,每个元素可以是数组或数字:
[[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#中没有任何一种类型)
答案 0 :(得分:4)
您的运营商应该返回MyArray
。此外,您应该实现MyArray
到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
,但其使用会带来重大的性能损失。
答案 1 :(得分:0)
您所代表的是一种逻辑“树”类型的数据结构,您只需要使用索引器来访问元素(如果您在编译时倾向于知道树的结构,那就很好了。) / p>
通常使用基于树的数据结构,复合模式是适用的。您有一个定义节点的接口,然后是两种实现它的类;一个用于叶子,一个用于父节点。然后,节点接口具有一些(或集合)其他节点(可以是实现,也可以是空集合,如果它是叶节点)。
这是一个稍微简单的实现,不使用接口;它不是那么强大(它更多地依赖于约定来告诉你发生了什么),但概念是相同的:
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];
}
}
}