Click here to Skip to main content
13,146,014 members (46,828 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

29.7K views
446 downloads
12 bookmarked
Posted 28 Apr 2013

Expression Based Property Getters and Setters

, 29 Apr 2013
Rate this:
Please Sign up or sign in to vote.
Expression Based Property Getters and Setters

Many times, I need to get or set properties on a class dynamically, i.e., not knowing their exact names at the compile times. Usually, I was doing it using System.Reflection API’s PropertyInfo class. This class provides GetValue() and SetValue methods that allow extracting or setting a value of a C# property based on the properties' name. The problem with this approach is that accessing a property dynamically using reflection API is very slow in comparison to accessing it via usual static API – in my tests, the difference was more than 60-fold.

I thought about using LINQ’s expression trees, instead. Nice thing about the expression trees is that they can be compiled in a way very similar to static compilation. It turned out that there are already examples of Expression getters and setters available on the internet, e.g., from Using expression trees to get property getter and setters and Creating a property setter delegate.

Based on the code described at the above URL, I built my own little Expression based getter and setter library:

// returns property getter
public static Func<TObject, TProperty> GetPropGetter<TObject, TProperty>(string propertyName)
{
    ParameterExpression paramExpression = Expression.Parameter(typeof(TObject), "value");

    Expression propertyGetterExpression = Expression.Property(paramExpression, propertyName);

    Func<TObject, TProperty> result =
        Expression.Lambda<Func<TObject, TProperty>>(propertyGetterExpression, paramExpression).Compile();

    return result;
}

// returns property setter:
public static Action<TObject, TProperty> GetPropSetter<TObject, TProperty>(string propertyName)
{            
    ParameterExpression paramExpression = Expression.Parameter(typeof(TObject));

    ParameterExpression paramExpression2 = Expression.Parameter(typeof(TProperty), propertyName);

    MemberExpression propertyGetterExpression = Expression.Property(paramExpression, propertyName);

    Action<TObject, TProperty> result = Expression.Lambda<Action<TObject, TProperty>>
    (
        Expression.Assign(propertyGetterExpression, paramExpression2), paramExpression, paramExpression2
    ).Compile();

    return result;
}

I also did some benchmarking comparing the speed of these getters and setters to those of:

  1. Direct statically compiled code setting and getting the properties
  2. Statically compiled lambdas
  3. Reflection based property getting and setting

Here are the results of running the getters and setters on 100000000 different objects with string properties:

Getters

Time (seconds)Getter Type
0.4Direct Statically Compiled
0.64Statically Compiled Lambda
2.0Compiled Expression based Getter
36.5Reflection based Getter

Setters

Time (seconds)Setter Type
0.7Direct Statically Compiled
1.0Statically Compiled Lambda
2.4Compiled Expression based Setter
50.6Reflection based Setter

You can see that even though the dynamically compiled expressions are 3-5 times slower than
statically compiled direct methods and 2-3 times slower than statically compiled lambdas, they are 18-20 times faster than Reflection based approach.

The code for the demo is located under CompiledExpressionTests.zip.

License

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

Share

About the Author

Nick Polyak
Architect AWebPros
United States United States
I have 15 years of experience developing enterprise software, starting from C++ and Java on UNIX and moving towards C# on Windows platforms.
I am fascinated by the new .NET technologies especially WPF, Silverlight and LINQ.
Recently I decided to make a move and start my own contracting consulting and mentoring company AWebPros.
I can be contacted via my web site awebpros.com or through my blog at nickssoftwareblog.com

You may also be interested in...

Comments and Discussions

 
QuestionCache the delegates Pin
Sarafian28-Apr-13 20:23
memberSarafian28-Apr-13 20:23 
AnswerRe: Cache the delegates Pin
Nick Polyak30-Apr-13 14:17
memberNick Polyak30-Apr-13 14:17 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170915.1 | Last Updated 29 Apr 2013
Article Copyright 2013 by Nick Polyak
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid