Put it together, then break it apart

Ian recently posted a question on how to make data-binding more type safe. While looking at his original solution, I realised how nice the new lambda expressions of C# are. They are typechecked, giving the programmer some safety, and can be decomposed.
 
Given a class like the following, we can represent the data binding against the Foo property using a lambda () => instance.Foo. This lambda is typechecked so we will get compile time errors if we try to use an unknown property.

public class A
{
 
public int Foo
  {
   
get
   
{
     
return 20;
    }
  }
}

 
Then later we can take this lambda expression apart to get the instance and the property information.

A instance1 = new A();
Expression<Func<int>> theFunction = () => instance1.Foo;

A instance2;
System.Reflection.
PropertyInfo property;
ExtractTargetAndProperty<
A>(theFunction, out instance2, out property);

This method to extract the instance and property can be easily written as:

static void ExtractTargetAndProperty<T>(Expression<Func<int>> xx, out T thisPointer, out System.Reflection.PropertyInfo member)
{
 
MemberExpression exp = (MemberExpression) xx.Body;
 
Expression thisValue = exp.Expression;
 
Expression<Func<T>> getThis = Expression.Lambda<Func<T>>(thisValue, null);
 
Func<T> thisFetcher = getThis.Compile();
  thisPointer = thisFetcher();
  member = (System.Reflection.
PropertyInfo) exp.Member;
}

The need to wrap the expression with a () => to delay the evaluation isn’t as tidy as I’d like. In languages like Common Lisp, macros are a great way to get the wrapping automatically added. Maybe we’ll get them in C# one day.

Advertisements
This entry was posted in Computers and Internet. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s