Search code examples
c#lambdapredicatefunc

Predicates and OrderBy , Func


I understand that predicates are delegate to function which return bool and take generic parameter, I understand that when I say:

mycustomer => mycustomer.fullname == 1

It actually means:

delegate (Customer mycustomer)
{
  return mycustomer.fullName == "John";
}

The paramter I'm passing in when I pass this lambda expression is:

public delegate bool Criteria<T>(T value) which is natively called Predicate

But what I don't understand is what it means when I say mycustomer=>mycustomer.fullname

In customers.OrderBy(mycustomer=>mycustomer.fullname);

How do I implement something like OrderBy? How do I tell a method which property to do action on ! like the previous example?

By example here is a case I want to make a method which get all values of a collection for a specific property :

list<string> mylist = customers.GetPropertyValues(cus=>cus.Fullname);

Thanks in advance.


Solution

  • The Func<TElement,TKey> is used to create an IComparer<TKey> which is used internally in an OrderedEnumerable to sort the items. When you do:

    var items = myList.OrderBy(i => i.SomeProperty);
    

    The OrderedEnumerable type is creating an IComparer<TKey> internally. In the above example, if i.SomeProperty were a String it would create an instance of IComparer<String> and then sort the items in the source enumerable using that comprarer on the SomeProperty member.

    In your last case:

    list<string> mylist = customers.GetPropertyValues(cus=>cus.Fullname);
    

    You do this using Select:

    var names = customers.Select(c => c.Fullname);
    

    Which will return an enumerable of String names. In the Select method, the Func<TSource, TResult> is used to select the target element to be added to the result.

    To replicate this yourself, you could do:

    public static IEnumerable<TMember> GetPropertyValues<TSource, TMember>
      (this IEnumerable<TSource> enumerable, Func<TSource, TMember> selector)
    {
      if (enumerable == null)
        throw new ArgumentNullException("enumerable");
    
      foreach (TSource item in enumerable)
      {
        yield return selector(item);
      }
    }