Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# WPF LINQ collections .NET4 , +
Background to problem: I have a
BindingList<T>
of dynamic objects. These objects are of some type of class which is created at runtime. This class can have 1 or 2 or 3 or more properties. Names of these properties can also be different everytime when this class is created.
e.g.
Class Data
{
Property Value1;
Property Value2;
Property Value3;
..
...
}
 
Next time this class can be
Class Data
{
Property Value1;
Property Value2;
}
 
Issue is: Based on some parameter I can get a value from user 'Value1'. Then I want to sort this list of dynamic objects on value of property 'Value1'.
Posted 23-Jan-13 18:41pm

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

You need to implement a Comparer[^], and pass it to the List.Sort[^] method.
But since you have dynamic objects, you need to use reflection to get the values. Use this[^] approach:
 
public class DynamicSerializableComparer : IComparer<object>
{
    string _property;
 
    public DynamicSerializableComparer(string property)
    {
        _property = property;
    }
 
    public int Compare(object stringA, object stringB)
    {
        string valueA = stringA.GetType().GetProperty(_property).GetValue();
        string valueB = stringB.GetType().GetProperty(_property).GetValue();
 
        return String.Compare(valueA, valueB);
    }
 
}
Of course, if the property you have is not string or not comparable as string, you should change the last statement accordingly.
 
[Update: some improvements, and a sample]
As I mentioned, you can't use OrderBy, since there is no property you can specify in the lambda expression.
 
public class DynamicSerializableComparer : IComparer<object>
{
    string _property;
 
    public DynamicSerializableComparer(string property)
    {
        _property = property;
    }
 
    public int Compare(object stringA, object stringB)
    {
        string valueA = (string)stringA.GetType().GetProperty(_property).GetValue(stringA, null);
        string valueB = (string)stringB.GetType().GetProperty(_property).GetValue(stringB, null);
 
        return String.Compare(valueA, valueB);
    }
}
 
void Main()
{
    var a1 = new { id = 1, name="Peter", email="a@x.com"};
    var a2 = new { id = 2, name="John", address="USA"};
    var a3 = new { id = 3, name="Robert", address="France"};
    var a4 = new { id = 4, name="Albert", position="Boss"};
 
    var a = new List<object> {a1, a2, a3, a4};
 
    a.Sort(new DynamicSerializableComparer("name"));
 
    a.Dump();
}
 
This sample will run directly in LinqPad[^] (I suggest you download it if you don't have it already, it is a must if you develop linq stuff...), but you can write a simple dumper or inspect the sorted list in VS. As you can see, there is not even a class defined, all objects are inline. Won't work if you change the constructor parameter to a property that's not common in all objects - in such case you have to decide and add logic to the comparer how to compare nonexistent properties. But you can use this sample to implement a comparer for your needs.
  Permalink  
v3
Comments
Pranav_Parashar at 24-Jan-13 3:53am
   
I ge ta complie time error: The type arguments for method 'System.Linq.Enumerable.OrderBy(System.Collections.Generic.IEnumerable, System.Func, System.Collections.Generic.IComparer)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Maybe this is because of the dynamic class that I am creating at runtime
Zoltán Zörgő at 24-Jan-13 12:38pm
   
No. OrderBy makes no sense in this context, since you can not reference a dynamic property at compile time in the lambda expression. You have to use Sort. I will post a more complex sample shortly.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 240
1 Kamal Rocks 184
2 CPallini 155
3 PIEBALDconsult 150
4 BillWoodruff 148
0 OriginalGriff 5,695
1 DamithSL 4,506
2 Maciej Los 4,007
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,180


Advertise | Privacy | Mobile
Web01 | 2.8.141216.1 | Last Updated 24 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100