S h o r t S t o r i e s

// Tales from software development

Using delegates for properties in C# 2.0

leave a comment »

Occasionally I stumble across a scenario where the best solution for a problem would be to pass a property as an argument to a method.

I don’t mean the value of the property, I mean the property itself, i.e. a reference to the property Get and Set accessors. The way to pass a method as an argument is to use a delegate but if you try creating a delegate for a property in .NET 2.0 you’ll get an error message indicating that this is not supported. I’ve always assumed that this was the end of the story as far as .NET 2.0 is concerned.

I’ve just finished a project that implemented a generic interface between my company’s clinical data system and any ODBC data source. The need to have a property passed as an argument came up again and this time I spent a few hours investigating whether I’d overlooked a means to do this.

It turns out there is a way to do what I wanted. It’s not pretty but it does what I need and it enables me to write a common routine for handling a number of data items that I’d otherwise have had to have implemented as several almost identical blocks of code.

The solution is to pass the property accessor using an anonymous delegate.

As an example, consider a method that processes a database date/time value depending on its value might, or might not, set the value of a property. Typically, it would set the property value only if the database date/time value is not null. You’d want to call the method like this, with the third argument being the property:

this.SetDateTimeField(dataReader, columnIndex, person.DeceasedDate)

 
The SetDateTimeField method would check whether the specified column value is null and the process the value accordingly, for example:

if (dataReader.IsDBNull(columnIndex))
{
    person.DeceasedDate = dataReader.GetDateTime(columnIndex);
}

 
The problem is how to pass a delegate for the property. The C# compiler will not permit you define the method with delegate argument and pass a delegate for the property:

Error: 'Person.DeceasedDate' is a 'property' but is used like a 'method'

 
There is a way to do this but, as mentioned at the start of this post, it isn’t pretty. The solution is to use an anonymous method to set the property value. The method needs to define a delegate argument and the easiest way to do this is to make use of the System.Action<T> delegate like this:

private void SetDateTimeFieldValue(DataReader reader, int columnIndex, Action<DateTime> dateTimeProperty)

 
The call is made like this:

this.SetDateTimeFieldValue(reader, columnIndex, delegate(DateTime value) { person.DeceasedDate = value; });

 
Not a perfect solution but better than the alternatives.

Advertisements

Written by Sea Monkey

January 27, 2011 at 8:00 pm

Posted in Development

Tagged with

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

%d bloggers like this: