反思和泛型的改进

时间:2011-08-02 21:58:25

标签: c# generics reflection

继续使用其他用户对Stack Overflow的另一个问题,我想我会尝试代码,看看我是否可以改进它。

我想澄清一些事情:

  1. 我假设通过反思获取房产信息费用昂贵?正确的吗?
  2. PropertyInfo.SetValue(Object, Object, Object[])最后一个参数是什么?我安全地传递null吗?
  3. 我的代码中是否还有明显的其他改进?
  4. 重点是一个学习练习,看看我是否可以创建像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 个答案:

答案 0 :(得分:2)

  1. 通过反射获取属性信息的成本很高,但通过反射访问属性也是如此。通过完全避免反思你可以从这种方法中获得几乎所有的收益。此外,除非您已确定此代码是性能瓶颈,否则此处的大多数优化都是不成熟的。
  2. 使用PropertyInfo.SetValue(Object,Object,Object []),最后一个参数与索引属性有关(例如dict[0]实际访问索引属性,并传递一个{{1}的数组在第三个参数中)。
  3. 我建议您为0使用ConcurrentDictionary。它将有助于简化代码并使其成为线程安全的。

答案 1 :(得分:1)

在性能方面,反射不是完全整数,不是。但是,在您使用它的情况下,这是否重要?

PropertyInfo.SetValue()的第三个参数用于设置属性索引器。这适用于类似数组的属性。在大多数情况下,这将是空的。

我没有看到任何明显的东西。但是看起来好像会出现隐藏的小角落案件等等很长一段时间。换句话说,这似乎是一个很棒的学习练习,这就是你想要的。

答案 2 :(得分:0)

听起来有点像你正在考虑编写AutoMapper,考虑到这个问题已经考虑了一些性能问题。