-1

Is there a way of passing in a method to a function as a parameter and then calling it via list.Sort()? I've tried this:

public static string BuildHumanSitemap(Func<TreeNode, TreeNode, int> sortMethod, params string[] classNames)
{
    //calling list sort on method passed as parameter
    nodes.sort(sortMethod);
 }

Where the functions i want to pass in all take the same params e.g.

private static int SortByDateCreated(TreeNode x, TreeNode y)
{
    DateTime xT = (DateTime)x["DocumentCreatedWhen"];
    DateTime yT = (DateTime)y["DocumentCreatedWhen"];
    return xT.CompareTo(yT);
}

I've also tried using an Action delegate type but the sort method complains when i pass it as a parameter. Can anyone offer a suggestion on how to do this?

Thankyou

DGibbs
  • 14,316
  • 7
  • 44
  • 83
  • Can you show us what you tried? Also, you said the sort method complains when you use Action, can you please post what the error message is? – Jetti Dec 21 '12 at 16:29
  • What's the type of `nodes`? And more specifically what's the signature for the `sort` method? – Brian Rasmussen Dec 21 '12 at 16:30
  • 1
    If you're talking about `List.Sort`, that method does not provide an overload that takes a delegate. – Andrew Whitaker Dec 21 '12 at 16:30
  • @BrianRasmussen `nodes` is a `List`. `Sort` is just a `List.Sort()`. @Andrew so i guess what i want to achieve is not possible? – DGibbs Dec 21 '12 at 16:33
  • @DGibbs: Not via any built-in library functions that I know of, you could write an extension method to do it though. – Andrew Whitaker Dec 21 '12 at 16:33
  • @AndrewWhitaker - thanks. It works when i call `nodes.Sort(SortByDateCreated);` rather than passing in a parameter which is why i thought it might be possible out of the box somehow – DGibbs Dec 21 '12 at 16:35
  • @DGibbs: Looks like I could be wrong--check out lazyberezovsky's answer below... – Andrew Whitaker Dec 21 '12 at 16:35
  • Yep, he has the solution. Thanks guys – DGibbs Dec 21 '12 at 16:37
  • @AndrewWhitaker Just for completeness, here's [the documentation for the `List.Sort` overload which takes in a delegate](http://msdn.microsoft.com/en-us/library/w56d4y5z.aspx). – Jeppe Stig Nielsen Dec 21 '12 at 18:49

4 Answers4

3

Create new Comparison delegate and pass it to Sort method:

nodes.Sort(new Comparison<TreeNode>(sortMethod));
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
2

Maybe instead of taking in a Func<,,> delegate, you should consume a Comparison<> delegate. Because that's what List<> wants (for historical reasons; the List<>.Sort method was written for .NET 2.0, before the Func delegates were introduced).

Therefore:

public static string BuildHumanSitemap(Comparison<TreeNode> sortMethod, params string[] classNames)
{
  //calling list sort on method passed as parameter
  nodes.Sort(sortMethod);
}

Then call your method very simply like this:

BuildHumanSitemap(SortByDateCreated);

where SortByDateCreated is the "method group" from your question.

There's no need for first creating a delegate instance of type Func<TreeNode, TreeNode, int> and then create another delegate instance (of type Comparison<TreeNode>) which references the first one.

Of course you can also call your BuildHumanSitemap method with a lambda arrow as the first argument.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
0

It works this way:

  TreeView.TreeViewNodeSorter = new CustomNodeSorter();

  private class CustomNodeSorter : IComparer
  {
     public int Compare(object x, object y)
     {
         DateTime xT = (DateTime)x["DocumentCreatedWhen"];
         DateTime yT = (DateTime)y["DocumentCreatedWhen"];
         return xT.CompareTo(yT);
     }
  }
VladL
  • 12,769
  • 10
  • 63
  • 83
0

Solution with IComparer<T>.

Comparer

public class MyTreeNodeComparer : IComparer<TreeNode>
{
     public int Compare(TreeNode x, TreeNode y)
     {
         DateTime xT = (DateTime)x["DocumentCreatedWhen"];
         DateTime yT = (DateTime)y["DocumentCreatedWhen"];
         return xT.CompareTo(yT);
     }
}

Usage

list.Sort(new MyTreeNodeComparer());
mipe34
  • 5,596
  • 3
  • 26
  • 38