The fictional example here. Suppose I designed a class named IODevice. This class already implements a structure that allows me to use it in the following way:
IODevice dio = new IODevice();
try
{
dio.Pin["IsBirdInCageSensor"].Set();
dio.Pin["KillBird"].Get();
//dio.Pin["NonExistant"].Set(); //exception
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Pins here are a series of IO lines in a digital IO box that can go high (1) or low (0).
I would like to use dynamic to call it in the following way:
dio.Pins.KillBird.Get();
My IO device class looks like this right now, and as you will notice, I haven’t advanced much on how to implement the dynamic interface, except for using the dynamic keyword.
class IODevice
{
public IODevice()
{
pin = new PinCollection();
pin.Add(new Pin("IsBirdInCageSensor", 0));
pin.Add(new Pin("KillBird", 1));
}
private PinCollection pin;
public PinCollection Pin { get { return pin; } }
public dynamic Pins { get; private set; }
}
The second question is: what are the disadvantages of using such design? (apart from the lack of hard type checking – which I don’t have anyways)
If you want to carry on using your existing
PinCollectiontype, then PinCollection needs to implement IDynamicMetaObjectProvider. Then Pins would return the same PinCollection as Pin, but because it was typed as dynamic would allow theobj.Pins.KillBirdsyntax (and your GetMetaObject implementation would translate this into dictionary accesses on PinCollection).If you can change your implementation, then you can instead use the ExpandoObject class:
ExpandoObject is basically a dictionary that already has a metaobject that translates dynamic property accesses into dictionary accesses. Note that in this case you would have to get rid of the strong-typed PinCollection, or figure out some way to synchronise the two: you don’t want different pin data stored in the two places.