0

What I'm trying to do is iterate over the country collection in retVal and sort each of the <StateProvinces> by Name. The hierarchy is as follows:

retVal[index].StateProvinces.ToList()[index].Name = "";

so that it is country object -> collection of states, each state has a name property and lazy loading it throwing state objects into an order based on the stateID.

What's wrong with this line of code (and why although I'm guessing I'm attempting to abuse the sort method)?

retVal[0].StateProvinces.ToList().Sort(x=>x.Name);

retVal is of type IList<Country>

Error is given for x=>x.Name:

Delegate 'System.Comparison<Country>' does not take 1 arguments
1
  • 1
    .OrderBy(x=>x.Name); Commented Jan 30, 2015 at 21:34

3 Answers 3

3

The Comparison delegate is a delegate that represents a comparison, not a projection. That is to say it takes two objects, and a result indicating which one is "smaller". You're trying to provide a projection, or a transformation of one object to another.

To write a comparison for two of these objects based on Name you'd need to write something like:

(a,b) => string.Compare(a.Name, b.Name);

You can also write a separate method to sort lists that uses a projection instead of a comparer, so that you don't need to do this for every call to Sort:

//TODO come up with a better name, but it still has to be different from `Sort`
public static void ProjectionSort<T, TKey>(
    this List<T> list,
    Func<T, TKey> selector,
    Comparer<TKey> comparer)
{
    comparer = comparer ?? Comparer<TKey>.Default;
    list.Sort((a, b) => comparer.Compare(selector(a), selector(b)));
}
Sign up to request clarification or add additional context in comments.

3 Comments

This works, kind of. I can watch it actually doing the comparisons but it's not actually storing the sorted objects back into retVal[index].StateProvinces. What am I doing wrong here?
@MetalPhoenix You're pulling all of the items out of the sequence, creating a new list to store that data, sorting that list, and then throwing that list away without ever doing anything with it. If you want to store the result in that property, you need to explicitly store the result back in that property.
Ah, I think I understand. I thought it wouldn't return anything since the return type in VS shows as "void." It also turns out that there's some mad hoodoo going on in a section of code I found today that I hadn't seen before deep in the bowels of the project architecture. Thanks for the advice.
2

As error says, Comparison<T> takes two argument not one, you want something like this:

retVal[0].StateProvinces.ToList().Sort((x,y) => x.Name.CompareTo(y.Name));

1 Comment

This will break if any names are null.
1

Ok.. I got very frustrated with this issue last night and this morning realized the real issue was that .Sort isn't there. The method you need to call to "Sort" your collections is .OrderBy.

Hopefully this helps someone to not pull out all their hair.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.