Wednesday, June 23, 2010

Compile-safe MemberInfo Selection

I have been playing around with Windows Forms in .NET and in particular the ComboBox control.

I decided to initialise the combo box like so:

private void SetComboData(IList<SupporterRecord> supporters)
{
var bindingSource = new BindingSource { DataSource = supporters };
comboBox1.DisplayMember = "OpportunityName";
comboBox1.ValueMember = "SupporterId";
comboBox1.DataSource = bindingSource;
}



Notice how the DisplayMember and ValueMember variables are being set by hardcoding the string name of the property that exists on the SupporterRecord class.

This is horrible because I get no compile-time checking of the Property names.

I want to be able to use a Lambda expression to do something like this:


// get the Property item via reflection
MemberInfo member = SupporterNumber.GetMemberinfo(s &eq;> s.OpportunityName);

// and get the name of the property
string name = member.Name;


I found a code snippet on the StackOverflow site to almost do this.

Thinking about this further I also want to be able to do this in the general case for all object types. In comes Extension Methods.


public static class ClassExtensions
{
public static MemberInfo GetMemberInfo<TSupporterRecord>(this TSupporterRecord r, Expression<func<TSupporterRecord, object>> expression)
{
var member = expression.Body as MemberExpression;
if (member == null)
throw new ArgumentException("expression returns no member.", "expression");

return member.Member;
}
}


Usage is as follows:


private void SetComboData(IList<SupporterRecord> supporters){
var bindingSource = new BindingSource { DataSource = supporters };
comboBox1.DisplayMember = ((SupporterRecord)null).GetMemberInfo(s => s.OpportunityName).Name;
comboBox1.ValueMember = ((SupporterRecord)null).GetMemberInfo(s => s.SupporterId).Name;
comboBox1.DataSource = bindingSource;
}



Now it is not entirely the way I want it but it is getting close as I want:


MemberInfo member = SupporterNumber.GetMemberinfo(s => s.OpportunityName);


which is a static method on the class so I started Googling for static extension methods but there is currently no implementation of this, but a number of people saying how cool it would be to have it.

Maybe in later releases of .NET we will see this and I'll be able to perfect my API.

Cheers

No comments:

Post a Comment