开发者

linq in plain english

Can someone explain in plain english the syntax of this:

开发者_JAVA百科Here is the signature of the OrderBy operator:

OrderedSequence<TElement> OrderBy<TElement, TKey>(
    this IEnumerable<TElement> source, 
    Func<TElement, TKey> keySelector
)

This shows that the type of the delegate you need to provide to OrderBy is Func<TElement, TKey>.

I'm looking to build a function that receives a list and a string as a parameter (the column name) and I'm stuck on the syntax of the OrderBy extension method. What does Func<...> mean? Where do I put the string parameter to sort with?

Thanks.


Here's how you might see it in practice, given

List<MyClass> list;

and

public class MyClass
{
    public string Name { get; set; }
    // ...
}

you might say

list.OrderBy(x => x.Name);

The this IEnumerable<TElement> source is how we know that we call this as an extension method off of any IEnumerable.

If you're using a dynamic property name, you're going to have to get more fancy. I'd first define a helper function to make sure our lambda doesn't get too messy. Note that for the sake of time and clarity to the concept being demonstrated, I've omitted some things like checks and error handling:

public object GetPropertyByName(object obj, string propertyName)
{
    object result = null;

    var prop = obj.GetType().GetProperty(propertyName);
    result = prop.GetValue(obj, null);

    return result;

}

Now use our helper as follows:

List<MyClass> list = new List<MyClass>();
list.Add(new MyClass { Name = "John" });
list.Add(new MyClass { Name = "David" });
list.Add(new MyClass { Name = "Adam" });
list.Add(new MyClass { Name = "Barry" });

const string desiredProperty = "Name"; // You can pass this in
var result = list.OrderBy(x => GetPropertyByName(x, desiredProperty));
foreach (MyClass c in result)
{
    Console.WriteLine(c.Name);
}


Alright, this guy is an extension method (from the this) that works on an IEnumerable of some thing (TElement). It takes a method that when given an element in the list, returns something you can sort by.

From: http://msdn.microsoft.com/en-us/library/bb534966.aspx

        class Pet
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        public static void OrderByEx1()
        {
            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);

            foreach (Pet pet in query)
            {
                Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
            }
        }

        /*
         This code produces the following output:

         Whiskers - 1
         Boots - 4
         Barley - 8
        */


U can use

(from o in listOfObjects
select o).OrderBy(p => p.columnname)

Here columnname is the column on which you want to do order by


Func<TElement, TKey> refers to a function that takes an argument of type TElement and returns a value of type TKey. You could specify the types when calling the function (e.g. foo.OrderBy<MyObject, string>(...)), but the compiler can usually infer them from the supplied function.

Now, OrderBy doesn't take a column name to sort by, it takes a function that takes the object to inspect as an argument and returns to the value to sort by. For example,

list.OrderBy(item => item.SortByField)

Of course, the function could be defined using something else besides lambda syntax (as a normal method for instance), but this is usually most convenient.

In order to sort by a runtime-defined property name, you'll have to come up with a way to make a function that extracts a value from the specified property. One way is to use reflection, another way would be to use the Expression class to construct a lambda expression on the fly and then compile it into a Func.

Here's an example (completely untested - but something along these lines)

using System.ComponentModel;

public static IEnumerable<TValue> OrderByField<TValue>(this IEnumerable<TValue> source, string fieldName) {
    PropertyDescriptor desc = TypeDescriptor.GetProperties(typeof(TValue))[fieldName];
    return source.OrderBy(item => desc.GetValue(item));
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜