【问题标题】:.Net Extension method for derived class (TreeNode).Net 派生类扩展方法(TreeNode)
【发布时间】:2014-05-08 23:33:30
【问题描述】:

我有一个树视图,并且想简单地返回满足给定条件的最深节点。

到目前为止,这个问题的答案是最有希望的: Searching a tree using LINQ

所以我可以这样做:

foreach(CustomTreeNode aNode in treMyTreeView.Nodes){

    List<TreeNode> EligibleNodes = 
        aNode.Descendants().Where(node => node.Tag == SomeCondition)

}

(我意识到我可能需要做更多工作才能从 TreeNode 转换为 CustomTreeNode)

但在我到达那里之前,我在尝试将扩展方法添加到 TreeNode 类时遇到了困难。

public class CustomTreeNode : TreeNode  {

    static IEnumerable<TreeNode> Descendants(this TreeNode root) {
        var nodes = new Stack<TreeNode>(new[] { root });
        while (nodes.Count > 0) {
            TreeNode node = nodes.Pop();
            yield return node;
            foreach (TreeNode n in node.Nodes) nodes.Push(n);
        }
    }

}

你会告诉我它必须是静态的,因此我不能从 TreeNode 派生。我不明白为什么。

我怎样才能达到上述(或类似的)?

【问题讨论】:

  • 您在尝试编译此方法时收到的错误消息将告诉您确切地为什么这不起作用。你只需要阅读错误信息。
  • 编译器错误告诉我“扩展方法必须在非泛型静态类中定义”是的,我可以阅读。但这对我来说毫无意义,因此这个问题需要帮助理解它。
  • 那么你定义扩展方法的类是非泛型的吗?它是一个静态类吗?我想您可以自己判断该类不是通用的,这只会使静态类中没有它。 “我如何使 C# 类静态化”的问题是 Google 可以非常简单地告知您的问题。那,或者您可以简单地查看您从中获得此代码的问题,因为它也在那里演示了这个概念。你甚至不需要能够阅读来解决这个问题;您只需将错误消息粘贴到 Google 即可解决。
  • 再次感谢您的积极鼓励。我显然对此很陌生,因此提出了寻求帮助的问题。我知道如何以及为什么要使一个类成为静态的,但我的困惑源于我试图覆盖 TreeNode 类。我以为我最终可以做 aNode.Descendants() ,但我没有意识到我应该只创建一个“in out”函数来在外部执行它。

标签: c# linq extension-methods derived-class


【解决方案1】:

只需将它放在一个静态帮助器类中,例如:

public static class CustomTreeNodeExtensions
{
    public static IEnumerable<TreeNode> Descendants(this TreeNode root)
    {
        // method
    }
}

扩展必须在静态类中。

但是如果你创建了一个CustomTreeNode 类,如果你直接将它添加到类中,为什么你希望它成为一个扩展方法?为什么不将其设为普通方法(如果您刚刚为扩展创建了 CustomTreeNode,这无关紧要 - 在这种情况下:包含扩展方法的类不需要从您尝试创建扩展的类继承方法)?

public class CustomTreeNode : TreeNode
{
    public IEnumerable<TreeNode> Descendants()
    {
        var nodes = new Stack<TreeNode>(new[] { this });
        // rest
    }
}

【讨论】:

  • 他不能使它成为实例方法,因为他不是能够编辑 TreeNode 类的 Microsoft 员工。
  • 但是他无论如何都在创建一个CustomTreeNode 类,不是吗?
  • 但他正在尝试将扩展方法添加到TreeNode。他似乎认为他需要创建该类的派生类型才能这样做。他错了。
  • 好的,可以这样。将其添加到“但部分”中-他的问题标题确实暗示了其他...
  • @Servy,是的,你是对的。我正在尝试实现单线返回满足给定条件的最深节点。我显然自欺欺人地认为我需要创建一个新的派生类。
【解决方案2】:

您必须在单独的静态类中声明扩展方法。

public static class NodeExtensions
{
    static IEnumerable<TreeNode> Descendants(this TreeNode root) {
        var nodes = new Stack<TreeNode>(new[] { root });
        while (nodes.Count > 0) {
            TreeNode node = nodes.Pop();
            yield return node;
            foreach (TreeNode n in node.Nodes) nodes.Push(n);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 2019-05-16
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多