C# c中自定义委托的示例用法
我发现了关于C中树实现的问题。我不知道委托,我想知道下面的代码如何用于实现树。另外,跟踪父节点最有效的方法是什么C# c中自定义委托的示例用法,c#,delegates,tree,parent-child,C#,Delegates,Tree,Parent Child,我发现了关于C中树实现的问题。我不知道委托,我想知道下面的代码如何用于实现树。另外,跟踪父节点最有效的方法是什么 delegate void TreeVisitor<T>(T nodeData); class NTree<T> { T data; LinkedList<NTree<T>> children; public NTree(T data) { this.data = data;
delegate void TreeVisitor<T>(T nodeData);
class NTree<T>
{
T data;
LinkedList<NTree<T>> children;
public NTree(T data)
{
this.data = data;
children = new LinkedList<NTree<T>>();
}
public void addChild(T data)
{
children.AddFirst(new NTree<T>(data));
}
public NTree<T> getChild(int i)
{
foreach (NTree<T> n in children)
if (--i == 0) return n;
return null;
}
public void traverse(NTree<T> node, TreeVisitor<T> visitor)
{
visitor(node.data);
foreach (NTree<T> kid in node.children)
traverse(kid, visitor);
}
}
委托基本上允许您谈论满足某些条件的任意函数,而不必确切地知道您所谈论的函数
考虑以下用于遍历树并对每个元素执行操作的代码:
void DoSomethingToAllNodes(NTree<T> node)
{
DoSomething(node);
foreach (var child in node.Children)
DoSomethingToAllNodes(child);
}
它是有效的,但它相当不灵活。我们必须为要在节点上执行的每个不同操作重新实现该方法:
void DoSomethingElseToAllNodes(NTree<T> node)
{
DoSomethingElse(node);
foreach (var child in node.Children)
DoSomethingElseToAllNodes(child);
}
相反,我们可以声明一个委托来表示以一个NTree作为参数的任何方法,但不返回任何内容,然后我们可以接受满足该条件的方法作为参数。然后,我们可以实现一个遍历方法来处理每一种可能性,而不必为每一个不同的操作重新实现它。委托基本上允许您谈论满足某些条件的任意函数,而不必确切地知道您在谈论什么函数
考虑以下用于遍历树并对每个元素执行操作的代码:
void DoSomethingToAllNodes(NTree<T> node)
{
DoSomething(node);
foreach (var child in node.Children)
DoSomethingToAllNodes(child);
}
它是有效的,但它相当不灵活。我们必须为要在节点上执行的每个不同操作重新实现该方法:
void DoSomethingElseToAllNodes(NTree<T> node)
{
DoSomethingElse(node);
foreach (var child in node.Children)
DoSomethingElseToAllNodes(child);
}
相反,我们可以声明一个委托来表示以一个NTree作为参数的任何方法,但不返回任何内容,然后我们可以接受满足该条件的方法作为参数。然后我们可以实现一种遍历所有可能的遍历方法,而不是必须为每个不同的操作重新实现它。
如果您完全熟悉C或C++,则可以将委托看作是类型安全的函数指针。这就是我如何设法让一个委托人对我与之交谈过的大多数人的看法。
< P>如果你完全熟悉C或C++,那么委托可以被认为是一种类型安全的函数指针。这就是我如何设法了解委托对我与之交谈过的大多数人的影响。您的代码所做的是声明一个委托,它基本上是一个方法的签名。traverse方法接受签名与您声明为参数的委托匹配的任何函数并调用它。为了好玩,一切都是通用的delegate void TreeVisitor<T>(T nodeData);
// This function takes a handle to a method as a parameter,
// and invokes that method for each node
public void traverse(NTree<T> node, TreeVisitor<T> visitor) {
visitor(node.data);
...
}
可以称之为:
public class MyEvilPlans {
public void WreakHavoc<int>(int nodeData) {
Console.WriteLine("The secret to life is: {0}", nodeData.ToString());
}
public void PlayWithTree() {
NTree<int> tree = new NTree<int>();
// Initialize tree
// If the tree has 47 nodes, WreakHavoc will be called 47 times,
// once for each node in the tree.
tree.traverse(WreakHavoc);
}
}
访问者模式允许您决定为树的每个节点执行什么代码。。。其他人控制树的实现,但您通过预定义的委托契约控制对树行为的响应。在某种程度上,它破坏了封装,因为您知道所调用方法的内部细节:它将为每个节点回调您。但这就是访问者模式的全部内容:
要回答问题的第二部分,如何跟踪父节点。。。你拥有的是非二叉树。为了能够从任何节点遍历备份树,您必须为每个NTree指定一个名为“parent”的NTree类型的成员。这应该由NTree的构造函数设置,以便:
// Added the handle to 'this'
children.AddFirst(new NTree<T>(data, this));
您可以找到关于非二叉树的精彩讨论。您的代码所做的是声明一个委托,它基本上是一个方法的签名。traverse方法接受签名与您声明为参数的委托匹配的任何函数并调用它。为了好玩,一切都是通用的
delegate void TreeVisitor<T>(T nodeData);
// This function takes a handle to a method as a parameter,
// and invokes that method for each node
public void traverse(NTree<T> node, TreeVisitor<T> visitor) {
visitor(node.data);
...
}
可以称之为:
public class MyEvilPlans {
public void WreakHavoc<int>(int nodeData) {
Console.WriteLine("The secret to life is: {0}", nodeData.ToString());
}
public void PlayWithTree() {
NTree<int> tree = new NTree<int>();
// Initialize tree
// If the tree has 47 nodes, WreakHavoc will be called 47 times,
// once for each node in the tree.
tree.traverse(WreakHavoc);
}
}
访问者模式允许您决定为树的每个节点执行什么代码。。。其他人控制树的实现,但您通过预定义的委托契约控制对树行为的响应。在某种程度上,它破坏了封装,因为您知道所调用方法的内部细节:它将为每个节点回调您。但这就是访问者模式的全部内容:
要回答问题的第二部分,如何跟踪父节点。。。你拥有的是非二叉树。为了能够从任何节点遍历备份树,您必须为每个NTree指定一个名为“parent”的NTree类型的成员。这应该由NTree的构造函数设置,以便:
// Added the handle to 'this'
children.AddFirst(new NTree<T>(data, this));
您可以找到关于非二叉树的精彩讨论。顺便说一句,对于返回void的委托,预定义的泛型操作委托已经足够好了,无需声明自己的操作。我听说过操作,但由于我对委托一无所知,所以我想从这里开始。顺便说一句,对于返回void的委托,预定义的通用操作委托已经足够好了,无需声明自己的操作。我听说过操作,但由于我对委托一无所知,所以我想我应该从这里开始。谢谢,这很好
这很有道理。谢谢你付出了额外的努力,把所有的代码都打出来。谢谢,这很有意义。谢谢你多做了一点,把所有的代码都打出来了