简体   繁体   中英

How to use a lambda expression as a parameter?

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.

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

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.

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

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

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM