我正在尝试编写一个通用方法来包装我们正在使用的SDK。 SDK提供表示我们的数据对象的“AFElement”对象,每个数据AFElement都有一个“AFAttributes”集合,映射到我们的数据对象的属性。
我创建了一个泛型方法,它使用反射来检查它所调用的对象的属性,并从AFElement.Attributes
获取它们(如果存在):
private T ConvertAFElementTo<T>(AFElement element, T item) where T : class, new()
{
PropertyInfo[] properties = item.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
//Get the Attribute object that represents this property
AFAttribute attribrute = element.Attributes[property.Name];
if (attribrute != null)
{
//check if we have the same type
if (property.PropertyType.Equals(attribrute.Type))
{
//set our property value to that of the attribute
var v = attribrute.GetValue().Value;
property.SetValue(item, v);
}
//check if we have an AFElement as an Attribute that will need converting to a data object
else if (attribrute.Type.Equals(typeof(AFElement)))
{
AFElement attributeElement = attribrute.GetValue().Value as AFElement;
Type attributeType = null;
//look up it's data type from the template
TypeConversionDictionary.TryGetValue(attributeElement.Template, out attributeType);
if (attributeType != null)
{
//set it as a .NET object
property.SetValue(item, ConvertAFElementTo(attributeElement, Activator.CreateInstance(attributeType)));
}
}
}
}
return item;
}
我的想法是,我可以在这个方法中抛出任何数据对象T并填充它们,并且它可以工作,除非它非常慢。
获得63个对象(每个属性11个,所有简单类型,如Guid,String和Single)大约需要10秒钟,93%的时间都在此转换方法中。我听说反射不是很有效,但效率是否低效?
我还有其他方法可以做到这一点,还是一种加快速度的方法?我甚至试图做一些通用的东西我是愚蠢的吗?
答案 0 :(得分:2)
执行反射时的一般规则是不要在执行时执行任何查找操作等,而只是在初始化步骤中执行一次。
在您的示例中,您可以拥有该方法的类,该类将在静态构造函数中执行反射查找 - 首次访问该类时的ONCE。然后,所有方法调用都将使用已经评估过的反射元素。
反思必须做很多事情 - 你真的通过充满活力来使它变得更加困难。
我建议你做更多的分析,找出哪些方法确实很慢;)尽量少做反射部分。
你可以拥有一个AFAMapper类,它可以为每对Source和Target进行初始化;)