yu_ominae
yu_ominae

Reputation: 2935

Getting property type and pass to generic method

Working in .Net 4.5.

I am making classes that encapsulate an ActiveX control (CadCorp SIS activeX control to be specific) and basically replicate some of the objects available internally to that control (but not externally). From the outside the properties of the internal objects have to be manipulated using an API which takes text strings.

In each class I end up writing properties for getting and setting values via the API and i's basically the same code over and over again, e.g. Control.GetInt(TargetDescripor, TargetIdentifier, PropertyName);, so I am trying to use generics to cut down code to a minimum. I now have a method like this:

public T GetPropertyValue<T>(ObjectTypes Target, string PropertyName, int TargetIdentifier = 0)

which identifies the correct API method and returns the required value.

I still have to call this method from every object with the correct descriptor and the correct property name. I have cut down on that further. For example if I get a property in one of the objects I use the following code:

public Class MyObject
{
    public bool MyObjectPropertyX
    {
        get { return this.GetProperty<bool>(); }
    }

    private const string _MyObjectPropertyX = "APICommandString";

    private T GetPropertyValue<T>([CallerMemberName] string PropertyName = null)
    {
        string apiCommand = (string)this.GetType().GetField("_" + PropertyName, BindingFlags.NonPublic | BindingFlags.Static).GetValue(this);

        // Call the method which executes the API command with the correct object
        // descriptor and get the value
    }
}

and this works just great.

Now I am wondering if it is possible in the property's getter to call the this.GetProperty<T>() with the type parameter being set automatically to the type of the property? Is that feasible? Or is what I've got now as good as it gets?

UPDATE

Also, I would be interested to know if there are any drawbacks to moving to this kind of method. I will have to make a LOT of API calls, so I am wondering if using reflection will actually slow this down compared to the original code where I called the appropriate method explicitly in each getter and setter?

Upvotes: 0

Views: 890

Answers (1)

Pondidum
Pondidum

Reputation: 11617

To address your first point, I don't think you will reduce the get code further without over complicating things; just specifiying the type seems fine to me.

If you want to be able to determine the property name without hardcoding a string, you can use This method with reflection.

On performance, I would say above all: Test it. If you find it is slow, then you could try caching you lookup of property actions. This code will wrap the reflected field.getValue call in a Func<string> so that the reflection lookup is not needed everytime. Bear in mind that the reflection api does some caching internally anyway, so there may be little benefit to this.

    private readonly IDictionary<String, Func<String>> _cache = new Dictionary<String, Func<String>>();

    private String GetApiCommand(String propertyName)
    {
        Func<String> command;
        if (_cache.TryGetValue(propertyName, out command))
        {
            return command();
        }

        var field = GetType().GetField("_" + propertyName, BindingFlags.NonPublic | BindingFlags.Static);//.GetValue(this);

        if (field != null)
        {
            Func<String> action = () => (String)field.GetValue(this);
            _cache[propertyName] = action;

            return action();
        }

        throw new NotSupportedException();
    }

Upvotes: 1

Related Questions