mercredi 28 novembre 2018

Using reflection to pass property accessors as constructor parameter

I'm currently trying to rewrite a service in a control system application that I'm maintaining in a more practical manner, to allow for easier changes in the future. However, I'm not an expert on C#, and I'm hung up on how to accomplish this.

Here is an example the old implementation:

public sealed class Power : ScalarObject {
    private OctetString power;

    public Power() : base(SnmpOid.POWER){}

    public override ISnmpData Data
    get 
    {
        return new OctetString(Cabinets[0].Configuration.Power.ToString());
    }
    set
    {
        Cabinets[0].Configuration.Power = value;
    }
}

There is currently one of these ScalarObject classes for every piece of data... over 200. Each must be instantiated then added to the object store, like so...

public Power _power = new Power();
store.Add(_power);

What I'm trying to do is make it so all 200 scalar objects can be instantiated from one class, so there isn't 200 class files that I have to maintain. The problem is, each of the current class files provides access to a property on an instance of a class (in the above example, Configuration is the class, Power is the property).

I'd like to create an SnmpObject class that can be instantiated with a reference to the property that it controls, however, properties can't be passed by reference. I know there are ways to pass property accessors using reflection, but I haven't had any success.

Something like...

public sealed class SnmpObject : ScalarObject {
    private OctetString data;

    public SnmpObject(ObjectIdentifier oid, /* delegate to access properties */) : base(oid){

    }

    public override ISnmpData Data
    get 
    {
        // get property access here, return stored value
    }
    set
    {
        // get property access here, set value
    }
}

Then instantiated by...

public SnmpObject _power = new SnmpObject(SnmpOid.POWER, /* access to property */)

Is this doable, or am I better off keeping the old implementation? I know there has to be a better way of doing this than the way it was originally written.





Aucun commentaire:

Enregistrer un commentaire