为通用树 C# 实现 IEnumerable
Implementing IEnumerable for generic tree c#
我有一个通用树 class,我想为其实现 IEnumerable 接口。之前在Whosebug上查到的问题跟我的问题有点不一样。我知道我在绞尽脑汁,但我不知道那是什么。这是我的代码:
class Node<T>: IEnumerable<T>
{
private T data;
private LinkedList<Node<T>> children;
public Node(T data)
{
this.data = data;
children = new LinkedList<Node<T>>();
}
public void AddChildNode(Node<T> node)
{
children.AddFirst(node);
}
public void MyTraverse(Node<T> node, List<T> visited)
{
visited.Add(node.data);
foreach (Node<T> kid in node.children)
MyTraverse(kid, visited);
}
public IEnumerator<T> GetEnumerator()
{
return children.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
在函数 GetEnumerator() 中,我遇到了一个我不知道如何修复的转换错误。谁能帮帮我?
您可能想要 IEnumerable<Node<T>>
接口实现(您正在枚举 nodes Node<T>
,而不是 T
实例)而不仅仅是 IEnumerable<T>
一个:
class Node<T>: IEnumerable<Node<T>> {
...
public IEnumerator<Node<T>> GetEnumerator() {
return children.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
问题是children
是这样定义的:
private LinkedList<Node<T>> children;
这意味着 children
是 IEnumerable<Node<T>>
,而不是 IEnumerable<T>
。
因为你想要它作为 IEnumerable<T>
你必须提取 data
成员。根据你的遍历方法是如何定义的,我还怀疑你希望它递归地下降到节点 children:
public IEnumerator<T> GetEnumerator()
{
yield return data;
foreach (var childNode in children)
foreach (var child in childNode)
yield return child;
}
如果您只想将其 return children,请使用此代码:
public IEnumerator<T> GetEnumerator()
{
return children.Select(node => node.data);
}
获取枚举器就像::
public IEnumerator<Node<T>> GetEnumerator()
{
return children.GetEnumerator();
}
public class Node : IEnumerable<Node>
{
public string Name { get; internal set; }
public string Value { get; internal set; }
public Node Parent { get; internal set; }
public List<Node> Children { get; internal set; }
public Node(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException($"{nameof(Name)}");
Name = name;
Children = new List<Node>();
}
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public IEnumerator<Node> GetEnumerator()
{
var self = this;
var queue = new Queue<Node>();
queue.Enqueue(self);
while (queue.Any())
{
yield return queue.Dequeue();
foreach (var child in self.Children)
queue.Enqueue(child);
}
}
}
此外,这也是可行的,而且代码更少:
public IEnumerator<Node> GetEnumerator()
{
var self = this;
yield return self;
foreach (var child in self.Children)
yield return child;
}
我有一个通用树 class,我想为其实现 IEnumerable 接口。之前在Whosebug上查到的问题跟我的问题有点不一样。我知道我在绞尽脑汁,但我不知道那是什么。这是我的代码:
class Node<T>: IEnumerable<T>
{
private T data;
private LinkedList<Node<T>> children;
public Node(T data)
{
this.data = data;
children = new LinkedList<Node<T>>();
}
public void AddChildNode(Node<T> node)
{
children.AddFirst(node);
}
public void MyTraverse(Node<T> node, List<T> visited)
{
visited.Add(node.data);
foreach (Node<T> kid in node.children)
MyTraverse(kid, visited);
}
public IEnumerator<T> GetEnumerator()
{
return children.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
在函数 GetEnumerator() 中,我遇到了一个我不知道如何修复的转换错误。谁能帮帮我?
您可能想要 IEnumerable<Node<T>>
接口实现(您正在枚举 nodes Node<T>
,而不是 T
实例)而不仅仅是 IEnumerable<T>
一个:
class Node<T>: IEnumerable<Node<T>> {
...
public IEnumerator<Node<T>> GetEnumerator() {
return children.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
问题是children
是这样定义的:
private LinkedList<Node<T>> children;
这意味着 children
是 IEnumerable<Node<T>>
,而不是 IEnumerable<T>
。
因为你想要它作为 IEnumerable<T>
你必须提取 data
成员。根据你的遍历方法是如何定义的,我还怀疑你希望它递归地下降到节点 children:
public IEnumerator<T> GetEnumerator()
{
yield return data;
foreach (var childNode in children)
foreach (var child in childNode)
yield return child;
}
如果您只想将其 return children,请使用此代码:
public IEnumerator<T> GetEnumerator()
{
return children.Select(node => node.data);
}
获取枚举器就像::
public IEnumerator<Node<T>> GetEnumerator()
{
return children.GetEnumerator();
}
public class Node : IEnumerable<Node>
{
public string Name { get; internal set; }
public string Value { get; internal set; }
public Node Parent { get; internal set; }
public List<Node> Children { get; internal set; }
public Node(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException($"{nameof(Name)}");
Name = name;
Children = new List<Node>();
}
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public IEnumerator<Node> GetEnumerator()
{
var self = this;
var queue = new Queue<Node>();
queue.Enqueue(self);
while (queue.Any())
{
yield return queue.Dequeue();
foreach (var child in self.Children)
queue.Enqueue(child);
}
}
}
此外,这也是可行的,而且代码更少:
public IEnumerator<Node> GetEnumerator()
{
var self = this;
yield return self;
foreach (var child in self.Children)
yield return child;
}