This is a theoretical question, I’ve already got a solution to my problem that took me down a different path, but I think the question is still potentially interesting.
Can I pass object properties as delegates in the same way I can with methods? For instance:
Let’s say I’ve got a data reader loaded up with data, and each field’s value needs to be passed into properties of differing types having been checked for DBNull. If attempting to get a single field, I might write something like:
if(!rdr["field1"].Equals(DBNull.Value)) myClass.Property1 = rdr["field1"];
But if I’ve got say 100 fields, that becomes unwieldy very quickly. There’s a couple of ways that a call to do this might look nice:
myClass.Property = GetDefaultOrValue<string>(rdr["field1"]); //Which incidentally is the route I took
Which might also look nice as an extension method:
myClass.Property = rdr["field1"].GetDefaultOrValue<string>();
Or:
SetPropertyFromDbValue<string>(myClass.Property1, rdr["field1"]); //Which is the one that I'm interested in on this theoretical level
In the second instance, the property would need to be passed as a delegate in order to set it.
So the question is in two parts:
- Is this possible?
- What would that look like?
[As this is only theoretical, answers in VB or C# are equally acceptable to me]
Edit: There’s some slick answers here. Thanks all.
(Adding a second answer because it’s on a completely different approach)
To address your original problem, which is more about wanting a nice API for mapping named values in a datareader to properties on your object, consider
System.ComponentModel.TypeDescriptor– an often overlooked alternative to doing reflective dirtywork yourself.Here’s a useful snippet:
That creates a dictionary of the propertydescriptors of your object.
Now I can do this:
PropertyDescriptor‘s SetValue method (unlikeSystem.Reflection.PropertyInfo‘s equivalent) will do type conversion for you – parse strings as ints, and so on.What’s useful about this is one can imagine an attribute-driven approach to iterating through that properties collection (
PropertyDescriptorhas anAttributesproperty to allow you to get any custom attributes that were added to the property) figuring out which value in the datareader to use; or having a method that receives a dictionary of propertyname – columnname mappings which iterates through and performs all those sets for you.I suspect an approach like this may give you the API shortcut you need in a way that lambda-expression reflective trickery – in this case – won’t.