为了提高效率而使用property.setvalue()的替代方法

时间:2012-09-12 19:44:31

标签: c# asp.net reflection

property.setvalue()有哪些替代方案?我读过它很慢。我用它来将IDataReader映射到POCO对象。

这是代码的截断版本。这里的一切对我来说都是新鲜的。我知道有很多框架可以完成这项任务。但是,我们不能使用它们。

public class DbAutoMapper<T>
{
    public IEnumerable<T> MapToList(IDataReader reader)
    {
        var list = new List<T>();

        while (reader.Read())
        {                
            var obj = Activator.CreateInstance<T>();

            foreach (PropertyInfo prop in obj.GetType().GetProperties())
            {
                foreach (var attribute in prop.GetCustomAttributes(true))
                {                        
                    prop.SetValue(obj, value, null);                        
                }
            }

            list.Add(obj);
        }
        return list;
    }
}

2 个答案:

答案 0 :(得分:5)

首先:当你不使用属性时,为什么要重复每个属性的反射?

第二:假设您打算按名称,列到属性(这不是代码当前所做的)映射,请考虑dapper之类的工具,为您完成所有这些工作,包括缓存的高性能反射 - 发射。它还将为您处理命令本身。例如:

string region = "North";
var customers = conn.Query<Customer>(
    @"select * from Customers where Region = @region",
    new { region } // full parameterization, the easy way
).ToList();

如果您需要更多控制,请考虑FastMember,它提供快速成员访问(同样,反射 - 发射),但不是特定于数据访问:

var accessor = TypeAccessor.Create(typeof(T)); 
string propName = // something known only at runtime 
while( /* some loop of data */ ) {
    var obj = new T();
    foreach(var col in cols) {
        string propName = // ...
        object cellValue = // ...
        accessor[obj, propName] = cellValue;
    }
    yield return obj;
}

答案 1 :(得分:1)

我想到了一些方法......

跳过反思

public class DbAutoMapper<T> where T : IInitFromReader, new()
{
    public IEnumerable<T> MapToList(IDataReader reader)
    {
        var list = new List<T>();

        while (reader.Read())
        {                
            IInitFromReader obj = new T;

            obj.InitFromReader(reader);

            list.Add(obj);
        }
        return list;
    }
}

然后,您必须在每个权利对象中实现InitFromReader。显然,这会减少反射的好处(代码较少)。

代码生成

为(InitFromReader)维护此代码很痛苦,因此您可以选择生成它。这在很多方面为您提供了两全其美的优势:

  • 您不必(手动)维护大量代码
  • 你不会受到反思的影响。