views:

121

answers:

5

i understand that predicates are delegate to function which return bool and take generic param , i understand that when i say

mycustomer => mycustomer.fullname == 1

it actually means:

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

the paramter im passing in when i pass this lambda expression is :

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

but what i dont 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.

+1  A: 

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);
  }
}
Matthew Abbott
thank you so much for your respond but i know i can use customers.select(c=>c.fullname) i just want to know how to implement something like that im not actually looking for getting values of a property i was just giving an example , the question is how to Implement a method like customers.GetPropertyValues(cus=>cus.Fullname); or customers.Select(c => c.Fullname); any method that you can specify a property name by using lambda expression.
Stacker
Updated answer.
Matthew Abbott
+3  A: 

You can create something like this:

static class ExtenstinonClass
{
    static IEnumerable<V> GetPropertyValues<T, V>(this IList<T> collection, Func<T, V> func)
    {
        foreach(var item in collection)
        {
            yield retun func(item);
        }
    }
}

But I really don't understand why Select method doesn't suite you.

Mike
im not against the select method , the thing is it doesnt answer the question , but your answer does ! i accepted your answer thank you so much , very nice
Stacker
+1  A: 

Hi,

The OrderBy Extension Method on class Enumerable takes a method of type Func as argument. Here is the documentation.

Here is another good article that you can use.

decyclone
nice post Decy , that answer is really nice ,expression tree is what im looking for, thanks...
Stacker
+1  A: 

how do i tell a method which property to do action on?

Create a method that takes another method which will select the values and invoke it on each element on a list.

Maybe this example will give you an idea:

class Program
{
    static void Main(string[] args)
    {
        DateTime[] test = { new DateTime(2010, 1, 1),
                            new DateTime(1845, 3, 6),
                            new DateTime(1948, 3, 8), 
                            DateTime.Now.AddDays(-10)};

        test.PrintSomething(d => (int)(DateTime.Now - d).TotalDays);
        Console.ReadLine();
    }
}

static class Ext
{
    public static void PrintSomething<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
    { 
        foreach(TSource element in source)
        {
            Console.WriteLine(String.Format("{0}: {1}", element.ToString(), selector(element).ToString()));
        }
    }
}
dkson
thanks i accepted that its so informative.
Stacker
+1  A: 

but what i dont understand is what it means when i say mycustomer=>mycustomer.fullname

It's the same thing as your delegate example except it only returns the fullName. Passed as a lambda so that it can be lazy evaluated.

If you want to create a method that works like OrderBy, besides that your GetPropertyValues seems to be the same as customers.Select(c => c.Fullname), then you'll have to dive into the sea of generics and extension methods. OrderBy is actually just an extension method on IEnumerable defined as

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

It looks like the answer from @Mike is an example of that and also a reimplementation of LINQ Select.

Jonas Elfström
i accepted that too, thanks
Stacker