C#Reflection Performence帮助

时间:2009-11-14 19:03:46

标签: c# performance reflection

        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();

此代码应查找名为blockName的值的属性。如果找到该属性,则应返回其值。如果没有,它应该查找名为blockName的值的函数。如果找到,则应调用它并返回返回的值。如果找不到该方法,则应返回[blockName's value]。

它运作良好,但我正在寻找提高效率的方法。我不想将方法转换为属性或属性到方法,因为将来我也会添加参数。你能帮帮我吗?

感谢。

3 个答案:

答案 0 :(得分:7)

如果你知道签名(即返回类型和参数),那么Delegate.CreateDelegate可以在这里非常有效地使用:

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);

    }
}

请注意,对于属性,您需要查看GetGetMethodGetSetMethod。如果您不知道签名,这不会很有效,因为DynamicInvoke非常慢。

要从Delegate.CreateDelegate中获益,必须缓存并重新使用委托实例;不要每次都重新创建它!

对于属性,即使您不知道属性类型,也可以考虑HyperDescriptor(您需要添加1行以启用超级描述符):

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);
    }
}

答案 1 :(得分:4)

你的主要问题是Type.GetProperty(...)和Type.GetMethod(...)非常慢。缓存从这些方法返回的值,您将看到一个巨大的加速(比此代码快20倍)。

虽然MethodInfo.Invoke和PropertyInfo.GetValue比直接调用慢,但它们对于大多数用途来说都很快。如果你真的需要,只能使用动态装配来优化它们 - 这是很多工作。

答案 2 :(得分:2)

执行此操作的一种方法是在第一次执行此代码时发出动态方法,并对其进行缓存。然后,后续调用执行预生成的方法,最终会非常快。如果重复执行此代码是您所看到的问题,那么这种方法可能适合您。如果我正在屠杀解释,请原谅我。

查看codeplex上的Dynamic Reflection Library