C # Reflection Performence Помощь - PullRequest
       24

C # Reflection Performence Помощь

4 голосов
/ 14 ноября 2009
        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 ]

7 голосов
/ 15 ноября 2009

Если вы знаете сигнатуры (то есть тип и параметры возврата), тогда 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);

    }
}

Обратите внимание, что для свойств, вы хотите посмотреть GetGetMethod и GetSetMethod. Это не так хорошо работает, если вы не знаете подпись, так как 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);
    }
}
4 голосов
/ 14 ноября 2009

Ваша основная проблема в том, что Type.GetProperty (...) и Type.GetMethod (...) работают очень медленно. Кэшируйте значения, возвращаемые этими методами, и вы увидите значительное ускорение (примерно в 20 раз быстрее для этого кода).

Хотя MethodInfo.Invoke и PropertyInfo.GetValue медленнее, чем прямые вызовы, для большинства целей они достаточно быстры. Оптимизируйте их, используя динамические сборки, только если вам действительно нужно - это много работы.

2 голосов
/ 14 ноября 2009

Один из способов сделать это - вызвать динамический метод при первом выполнении этого кода и кэшировать его. Затем последующие вызовы выполняют предварительно сгенерированный метод, который оказывается довольно быстрым. Если повторяющееся выполнение этого кода является проблемой, с которой вы сталкиваетесь, тогда этот подход может вам помочь. И, пожалуйста, прости меня, если я убиваю объяснение.

Взгляните на библиотеку динамических отражений на codeplex.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...