Reputation: 113
Assume I have a collection of the form:
List<Member> myMembers= new List<Member>()
{
new Member(){ID=1,FirstName="John",LastName="Doe"},
new Member(){ID=3,FirstName="Allan",LastName="Jones"},
new Member(){ID=2,FirstName="Martin",LastName="Moe"},
new Member(){ID=4,FirstName="Ludwig",LastName="Issac"}
};
I can sort this list via FirstName by using:
myMembers.Sort((x, y) => x.FirstName.CompareTo(y.FirstName));
I would like to do this inside of a function, so that I can pass the desired search parameter. Something like:
public void sortCollection( parameter SearchTerm, List<Member> myCollection )
{
myCollection ((x, y) => x.SearchTerm.CompareTo(y.FirstName));
}
Obviously here, I cannot pass in the desired search field this way, but is it possible to do what I am asking?
Upvotes: 0
Views: 173
Reputation: 23228
You can create a generic extension method for that and pass Func<T, TResult>
delegate to it, which is used as key selector for built-in Sort
method
public static void SortExt<T, TValue>(this List<T> collection, Func<T, TValue> selector)
{
var comparer = Comparer<TValue>.Default;
collection.Sort((x, y) => comparer.Compare(selector(x), selector(y)));
}
Keep in mind that you should compare the same fields of compared objects.
Example of the usage
myMembers.SortExt(member => member.FirstName);
If you want to compare the myMembers
collection only, the declaration can be simplified
public static void SortExt<TValue>(this List<Member> members, Func<Member, TValue> selector)
{
var comparer = Comparer<TValue>.Default;
members.Sort((x, y) => comparer.Compare(selector(x), selector(y)));
}
Another option is to introduce a Comparison<T>
delegate instance to store the logic of field comparison and pass it to the Sort
method. Here you can specify any custom comparison that you want
Comparison<Member> comparison = (x, y) => x.FirstName.CompareTo(y.FirstName);
myMembers.Sort(comparison);
Upvotes: 1
Reputation: 672
Why not simply use the built in function?
myMembers.OrderBy(m => m.FirstName)
If you really want to, you can write your own wrapper around this function, but the call would look more or less identical and would kind of be reinventing the wheel.
something like this extension method:
public static IEnumerable<T> OrderByWrapper<T, TKey>(this IEnumerable<T> source, Func<T,TKey> keySelector)
{
return source.OrderBy(keySelector);
}
you would call it with:
myMembers.OrderByWrapper(m => m.FirstName)
Upvotes: 0
Reputation: 16059
Instead of writing one more wrapper on Linq .OrderBy()
or .Sort()
method and calling that where ever you want to sort, use Linq OrderBy()
or .Sort()
method
Use Sort()
like
//If you want to sort collection by Id then
myMembers.Sort(x => x.Id);
//If you want to sort collection by FirstName then
myMembers.Sort(x => x.FirstName);
...
To decide between OrderBy()/Sort() read below Q&A thread
C# Sort and OrderBy comparison
Upvotes: 0
Reputation: 14218
It seems to me that you can use Func<> to be able to dynamic order by.
var result = sortCollection(p => p.ID, myMembers);
public static IEnumerable<Member> sortCollection(Func<Member, object> keySelector, List<Member> myCollection)
{
return myCollection.OrderBy(keySelector);
}
Read the following post to have a better understanding
Upvotes: 0