views:

54

answers:

1

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)

+2  A: 

If you want to carry on using your existing PinCollection type, then PinCollection needs to implement IDynamicMetaObjectProvider. Then Pins would return the same PinCollection as Pin, but because it was typed as dynamic would allow the obj.Pins.KillBird syntax (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:

private ExpandoObject _pins;
public dynamic Pins { get { return _pins; } }

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.

itowlson
@itowlson: Good suggestion, and +1 for mentioning ExpandoObject.@Padu: Checkout the C# example here[http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(VS.100).aspx], might help.
KMan
@KMan: the link is not working here
Padu Merloti
Padu: there's an extraneous ] on the end of KMan's link. Just delete that. But I think it goes to the same place as the ExpandoObject link in the answer body.
itowlson
Just couple more links with examples:http://blogs.msdn.com/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx (ExpandoObject) and http://blogs.msdn.com/csharpfaq/archive/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject.aspx (DynamicObject)
Alexandra Rusina