Улучшения с отражением и дженериками - PullRequest
1 голос
/ 03 августа 2011

Исходя из другого вопроса по Переполнение стека другим пользователем, я подумал, что попробую код и посмотрю, смогу ли я его улучшить.

Я хотел бы получить разъяснения по ряду вещей:

  1. Я предполагаю, что получение информации о недвижимости с помощью размышлений является дорогостоящим? Правильно?
  2. С PropertyInfo.SetValue(Object, Object, Object[]) для чего нужен последний параметр? Я в безопасности, переходя в ноль?
  3. Есть ли другие улучшения, которые очевидны в моем коде?

Весь смысл в обучающем упражнении, чтобы посмотреть, смогу ли я создать что-то вроде Dapper (что очень приятно) , но без отвратительного вида (потому что я понятия не имею) IL выбрасывать вещи. Имея это в виду, я попытался реализовать какое-то кэширование, предполагая, что отражение плохо влияет на производительность.


Код

    private T CreateItemFromRow<T>(SqlDataReader row, List<PropertyInfo> properties, Dictionary<String, Int32> schema) where T : new()
    {
        T item = new T();
        if (schema != null && properties != null && row != null)
        {
            foreach (var property in properties)
            {
                if (schema.ContainsKey(property.Name))
                {
                    // is this ok?
                    if (row[0].GetType() == property.PropertyType)
                    {
                        property.SetValue(item, row[schema[property.Name]], null);
                    }
                    else
                    {
                        property.SetValue(item, Convert.ChangeType(row[schema[property.Name]], property.PropertyType), null);
                    }
                }
            }
        }
        return item;
    }

Свойства передаются из этого метода:

    private List<PropertyInfo> GetPropertyInformation<T>()
    {
        List<PropertyInfo> properties;

        Type _T = typeof(T);
        if (!PropertyCache.ContainsKey(_T))
        {
            properties = _T.GetProperties().ToList();
            PropertyCache.Add(_T, properties);
        }
        else
        {
            properties = PropertyCache[_T];
        }
        return properties;
    }

А это декларация PropertyCache

private static Dictionary<Type, List<PropertyInfo>> PropertyCache { get; set; }

Ответы [ 3 ]

2 голосов
/ 03 августа 2011
  1. Получение информации о свойствах с помощью отражения обходится дорого, но доступ к свойствам с помощью отражения также является дорогостоящим. Вы не получаете от такого подхода почти столько же, сколько могли бы получить, полностью избегая рефлексии. Кроме того, если вы не определили, что этот код является узким местом в производительности, большая часть оптимизации в любом случае будет преждевременной.
  2. При использовании PropertyInfo.SetValue (Object, Object, Object []) последний параметр связан со свойствами индекса (например, dict[0] фактически обращается к свойству индекса и передает массив с 0 в этой третьей параметр).
  3. Я бы предложил использовать ConcurrentDictionary для PropertyCache. Это поможет как упростить ваш код, так и сделать его поточно-ориентированным.
1 голос
/ 03 августа 2011

Отражение не является целочисленным сложением, когда дело касается производительности, нет.Но имеет ли это значение в случае, когда вы используете его?

Третий аргумент PropertyInfo.SetValue() предназначен для установки индексаторов свойств.Это для свойств, которые похожи на массив.В большинстве случаев это будет нулевым.

Я не вижу ничего очевидного.Но это похоже на то, что в течение долгого времени можно найти скрытые маленькие угловые ящики и так далее.Другими словами, это похоже на фантастическое учебное упражнение, которое вы и хотели.

0 голосов
/ 23 марта 2013

Звучит так, будто вы подумываете о написании AutoMapper , в котором были учтены некоторые соображения по поводу этой проблемы.

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