Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Reflection Performence Help

        var property = obj.GetType().GetProperty(blockName);

        if (property == null)
        {
            var method = obj.GetType().GetMethod(blockName);

            if (method == null)
                return "[" + blockName + "]";
            else
                return method.Invoke(obj, null).ToString();
        }
        else
            return property.GetValue(obj, null).ToString();

This code should look for a property named blockName's value. If the property found, it should return its value. If not, it should look for function named blockName's value. If it finds, it should call it and return the returned value. If it dosen't find the method, it should return [blockName's value].

It's working great, but I'm looking for ways to make it more efficient. I don't want to convert methods to properties or properties to methods, because in the future I'll add parameters too. Can you help me please?

Thanks.

like image 848
Alon Gubkin Avatar asked Dec 13 '22 01:12

Alon Gubkin


1 Answers

If you know the signatures (i.e. the return type and parameters), then Delegate.CreateDelegate can be used very effectively here:

using System;
using System.Reflection;
class Test
{
    public string Foo(int i)
    {
        return i.ToString();
    }
    static void Main()
    {
        MethodInfo method = typeof(Test).GetMethod("Foo");
        Func<Test, int, string> func = (Func<Test, int, string>)
            Delegate.CreateDelegate(typeof(Func<Test, int, string>), null, method);
        Test t = new Test();
        string s = func(t, 123);

    }
}

Note that for properties, you want to look at GetGetMethod and GetSetMethod. This doesn't work so well if you don't know the signature, as DynamicInvoke is very slow.

To get benefit from Delegate.CreateDelegate, you must cache and re-use the delegate instance; don't recreate it each time!

For properties, even if you don't know the property-type, then perhaps consider HyperDescriptor (you need to add the 1-line to enable hyper-descriptor):

using System.ComponentModel;
class Test
{
    public int Bar { get; set; }
    static void Main()
    {
        PropertyDescriptor prop = TypeDescriptor.GetProperties(
            typeof(Test))["Bar"];
        Test t = new Test();
        t.Bar = 123;
        object val = prop.GetValue(t);
    }
}
like image 167
Marc Gravell Avatar answered Dec 15 '22 14:12

Marc Gravell