Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
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 17: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<tsource,tkey>(System.Collections.Generic.IEnumerable, System.Func<tsource,tkey>, 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
Your Filters
Interested
Ignored
     
0 Shai Vashdi 1,518
1 OriginalGriff 478
2 Manas Bhardwaj 394
3 Tadit Dash 310
4 Damith Weerasinghe 260
0 Sergey Alexandrovich Kryukov 9,575
1 OriginalGriff 5,856
2 Peter Leow 4,405
3 Maciej Los 3,540
4 Abhinav S 3,513


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