Click here to Skip to main content
15,884,298 members
Articles / Programming Languages / C# 4.0

Dumping Objects Using Expression Trees

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
11 Aug 2010CPOL1 min read 29K   21   8
Dumping Objects using Expression Trees

No. I'm not proposing to get rid of objects.

A colleague of mine was asked if I knew a way to dump a list of objects of an unknown type into a DataTable with better performance than the way he was using.

The objects being dumped usually have over a dozen properties, but, for the sake of this post, let’s assume they look like this:

C#
class SomeClass
{
    public int Property1 { get; set; }
    public long Property2 { get; set; }
    public string Property3 { get; set; }
    public object Property4 { get; set; }
    public DateTimeOffset Property5 { get; set; }
}

The code he was using was something like this:

C#
var properties = objectType.GetProperties();

foreach (object obj in objects)
{
    foreach (var property in properties)
    {
        property.GetValue(obj, null);
    }
}

For a list of one million objects, this takes a little over 6000 milliseconds on my machine.

I immediately thought of Expression Trees!

If the type of the objects was known at compile time, it would be something like this:

C#
Expression<Func<SomeClass, int>> expression = o => o.Property1;
var compiled = expression.Compile();
var propertyValue = compiled.Invoke(obj);

But, at compile time, the type of the object and, consequently, the type of its properties, is unknown. So, we'll need, for each property, an expression tree like this:

C#
Expression<Func<object, object>> expression = o => ((SomeClass)o).Property1;

The previous expression gets the value of a property of the conversion of the parameter of type object to the type of the object. The result must also be converted to type object because the type of the result must match the type of the return value of the expression.

For the same type of objects, the collection of property accessors would be built this way:

C#
var compiledExpressions = (from property in properties
                           let objectParameter = Expression.Parameter(typeof(object), "o")
                           select
                             Expression.Lambda<Func<object, object>>(
                                 Expression.Convert(
                                     Expression.Property(
                                         Expression.Convert(
                                             objectParameter,
                                             objectType
                                         ),
                                         property
                                     ),
                                     typeof(object)
                                 ),
                                 objectParameter
                             ).Compile()).ToArray();

Looks a bit overcomplicated, but reading all properties of all objects for the same object set with this code:

C#
foreach (object obj in objects)
{
    foreach (var compiledExpression in compiledExpressions)
    {
        compiledExpression(obj);
    }
}

takes a little over 150 milliseconds on my machine.

That’s right. 2.5% of the previous time.

 

License

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


Written By
Software Developer (Senior) Paulo Morgado
Portugal Portugal

Comments and Discussions

 
GeneralAwesome Pin
jason baisden17-Aug-10 3:32
jason baisden17-Aug-10 3:32 
GeneralRe: Awesome Pin
Paulo Morgado17-Aug-10 15:56
professionalPaulo Morgado17-Aug-10 15:56 
GeneralExcellent technique [modified] Pin
abdurahman ibn hattab6-Aug-10 13:18
abdurahman ibn hattab6-Aug-10 13:18 
GeneralRe: Excellent technique Pin
Paulo Morgado7-Aug-10 1:59
professionalPaulo Morgado7-Aug-10 1:59 
QuestionInteresting technique, that I'd like to learn. Pin
eobeda3-Aug-10 13:13
eobeda3-Aug-10 13:13 
AnswerRe: Interesting technique, that I'd like to learn. Pin
Paulo Morgado3-Aug-10 13:41
professionalPaulo Morgado3-Aug-10 13:41 
GeneralRe: Interesting technique, that I'd like to learn. Pin
baruchl11-Aug-10 2:25
baruchl11-Aug-10 2:25 
GeneralRe: Interesting technique, that I'd like to learn. Pin
Paulo Morgado11-Aug-10 15:45
professionalPaulo Morgado11-Aug-10 15:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.