-1

I have a treeview, and want to simply return the deepest node that satisfies a given condition.

The answer to this question is the most promising so far: Searching a tree using LINQ

So I could do this:

foreach(CustomTreeNode aNode in treMyTreeView.Nodes){

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

}

(I realise I might have a bit more work to do to cast from TreeNode to CustomTreeNode)

But before I even get there, I'm getting stuck trying to add the extension method to the TreeNode class.

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);
        }
    }

}

You'll tell me it needs to be static, and therefore I can't derive from TreeNode. And I don't understand why.

How can I achieve the above (or something similar)?

Community
  • 1
  • 1
user1830285
  • 578
  • 8
  • 24
  • 2
    The error message that you get when attempting to compile this method will tell you *exactly* why this doesn't work. You only need to read the error message. – Servy May 08 '14 at 15:29
  • The compiler error tells me "extension method must be defined in a non-generic static class" yes, I can read. It means nothing to me though, hence the question asking for help understanding it. – user1830285 May 08 '14 at 15:43
  • So is the class that you defined the extension method in non-generic? Is it a static class? I would imagine that you could tell that the class isn't generic yourself, which only leaves not having it in a static class. The question of "how do I make a C# class static" is something that Google can inform you of quite trivially. That, or you could simply have looked at the question that you got this code from, as it demonstrates the concept there as well. You *don't* even need to be able to read to solve this problem; you only need to stick the error message into Google to solve it. – Servy May 08 '14 at 15:46
  • Thank you again for your positive encouragement. I am clearly new to this, hence the question for help. I know how and why to make a class static, but my confusion has arisen from my attempts to override the TreeNode class. I thought I would be able to do aNode.Descendants() eventually, but I hadn't realised I should just create an "in out" function to perform it externally. – user1830285 May 08 '14 at 15:52

2 Answers2

3

Just put it in a static helper class like:

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

Extensions are required to be in a static class.

BUT IF you create a CustomTreeNode class anyhow why do you want it to be an extension method if you add it to the class directly? Why not make it a normal method (If you just created CustomTreeNode for the extension this is irrelevant - in that case: the class containing the extension method is NOT required to inherit from the class you are trying to create the extension method for)?

public class CustomTreeNode : TreeNode
{
    public IEnumerable<TreeNode> Descendants()
    {
        var nodes = new Stack<TreeNode>(new[] { this });
        // rest
    }
}
Christoph Fink
  • 22,727
  • 9
  • 68
  • 113
  • He can't make it an instance method because he isn't a Microsoft employee capable of editing their TreeNode class. – Servy May 08 '14 at 15:28
  • But he is creating a `CustomTreeNode` class anyhow, isn't he? – Christoph Fink May 08 '14 at 15:29
  • But he's trying to add an extension method to `TreeNode`. He seems to be under the impression that he needs to create a derived type of that class to do so. He is wrong. – Servy May 08 '14 at 15:30
  • Ok, could be that way. Added that to the "but-part" - his question title does suggest otherwise... – Christoph Fink May 08 '14 at 15:35
  • @Servy, Yes you're correct. I'm trying to achieve a one-liner to return the deepest node that satisfies a given condition. I have clearly fooled myself into thinking I need to create a new derived class. – user1830285 May 08 '14 at 15:40
  • What I'm struggling to understand, is how I link the static class (totally unrelated to TreeNode) to the actual TreeNode instances? How do I actually use this code? – user1830285 May 08 '14 at 15:41
  • Ignore that, got it. Simple when you know how. Thanks for your assistance. – user1830285 May 08 '14 at 15:52
0

You have to declare the extension method in separate, static class.

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);
        }
    }
}
jpmnteiro
  • 747
  • 1
  • 13
  • 23