Reputation: 10650
I have below method:
private List<TSource> Sort<TSource, TKey>(
List<TSource> list,
Func<TSource, TKey> sorter,
SortDirection direction)
{
...
}
and depending on the case, the parameter Func<TSource,TKey>
changes, for example, I have following switch:
public class CustomType
{
string Name {get; set;}
string Surname {get; set;}
...
}
switch (sortBy)
{
case "name":
orderedList = this.Sort<CustomType, string>(
lstCustomTypes,
s => s.Name.ToString(),
direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
break;
case "surname":
orderedList = this.Sort<CustomType, string>(
lstCustomTypes,
s => s.Surname.ToString(),
direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
break;
}
so, as you can observe in those cases, the call is always the same except for the lambda parameter s => something
, s => something2
so for no repeat code I would like to the something similar to:
switch (sortBy)
{
case "name":
lambdaExpresion = s => s.Name.ToString();
break;
case "surname":
lambdaExpresion= s => s.Surname.ToString();
break;
}
orderedList = this.Sort<CustomType, string>(
lstCustomTypes,
lambdaExpresion,
direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
I am not sure if it is possible, but if so how to achieve this? I do not want to repeat code.
Upvotes: 3
Views: 188
Reputation: 28747
Yes, you can just assign the lambda to a variable:
Func<CustomType, string> lambda;
switch (sortBy)
{
case "name":
lambda = s => s.Name.ToString();
break;
case "surname":
lambda = s => s.Surname.ToString();
break;
}
orderedList = this.Sort<CustomType, string>(
lstCustomTypes,
lambda,
direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
Upvotes: 4
Reputation: 6144
You can define a variable to hold your function as such,
Func<CustomType, string> lambdaExpresion;
and then assign it in your switch
block, like this,
switch (sortBy)
{
case "name":
lambda = s => s.Name;
break;
case "surname":
lambda = s => s.Surname;
break;
}
Upvotes: 1
Reputation: 2709
You already got correct answers. However, perhaps you should just use OrderBy and OrderByDescending instead:
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderby.aspx
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderbydescending.aspx
Example from the first link:
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };
IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);
Upvotes: 0
Reputation: 26951
Ok, just in case nobody uses reflection :)
orderedList = this.Sort<CustomType, string>(
lstCustomTypes,
s => s.GetType().GetProperty(sortBy).GetValue(s).Tostring(),
direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
Just watch out for the non-existing props or fields, incompatible names (like you might want to capitalize the first letter). error checking left as an excersice (because I don't have a box to test this code right now)
Upvotes: 0
Reputation: 203825
You were basically there already:
Func<CustomType, string> lambdaExpresion;
switch (sortBy)
{
case "name":
lambdaExpresion = s => s.Name.ToString();
break;
case "surname":
lambdaExpresion = s => s.Surname.ToString();
break;
case default: //need a default value for it to be definitely assigned.
lambdaExpresion = s => "";
}
orderedList = this.Sort(lstCustomTypes, lambdaExpresion,
direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
Upvotes: 0
Reputation: 13521
Declare the lambda variable first:
Func<CustomType, string> lambdaExpresion;
Before the switch
statement. This is possible because type of lambda in both cases are the same; otherwise it would not be possible.
Upvotes: 1