The simple demo below captures what I am trying to do. In the real program, I have to use the object initialiser block since it is reading a list in a LINQ to SQL select expression, and there is a value that that I want to read off the database and store on the object, but the object doesn’t have a simple property that I can set for that value. Instead it has an XML data store.
It looks like I can’t call an extension method in the object initialiser block, and that I can’t attach a property using extension methods.
So am I out of luck with this approach? The only alternative seems to be to persuade the owner of the base class to modify it for this scenario.
I have an existing solution where I subclass BaseDataObject, but this has problems too that don’t show up in this simple example. The objects are persisted and restored as BaseDataObject – the casts and tests would get complex.
public class BaseDataObject { // internal data store private Dictionary<string, object> attachedData = new Dictionary<string, object>(); public void SetData(string key, object value) { attachedData[key] = value; } public object GetData(string key) { return attachedData[key]; } public int SomeValue { get; set; } public int SomeOtherValue { get; set; } } public static class Extensions { public static void SetBarValue(this BaseDataObject dataObject, int barValue) { /// Cannot attach a property to BaseDataObject? dataObject.SetData('bar', barValue); } } public class TestDemo { public void CreateTest() { // this works BaseDataObject test1 = new BaseDataObject { SomeValue = 3, SomeOtherValue = 4 }; // this does not work - it does not compile // cannot use extension method in the initialiser block // cannot make an exension property BaseDataObject test2 = new BaseDataObject { SomeValue = 3, SomeOtherValue = 4, SetBarValue(5) }; } }
One of the answers (from mattlant) suggests using a fluent interface style extension method. e.g.:
// fluent interface style public static BaseDataObject SetBarValueWithReturn(this BaseDataObject dataObject, int barValue) { dataObject.SetData('bar', barValue); return dataObject; } // this works BaseDataObject test3 = (new BaseDataObject { SomeValue = 3, SomeOtherValue = 4 }).SetBarValueWithReturn(5);
But will this work in a LINQ query?
Even better:
and you can use this extension method for derived types of BaseDataObject to chain methods without casts and preserve the real type when inferred into a var field or anonymous type.