非常慢反射(尝试编写通用包装器)

时间:2016-03-21 09:51:46

标签: c# reflection

我正在尝试编写一个通用方法来包装我们正在使用的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%的时间都在此转换方法中。我听说反射不是很有效,但效率是否低效?

我还有其他方法可以做到这一点,还是一种加快速度的方法?我甚至试图做一些通用的东西我是愚蠢的吗?

1 个答案:

答案 0 :(得分:2)

执行反射时的一般规则是不要在执行时执行任何查找操作等,而只是在初始化步骤中执行一次。

在您的示例中,您可以拥有该方法的类,该类将在静态构造函数中执行反射查找 - 首次访问该类时的ONCE。然后,所有方法调用都将使用已经评估过的反射元素。

反思必须做很多事情 - 你真的通过充满活力来使它变得更加困难。

我建议你做更多的分析,找出哪些方法确实很慢;)尽量少做反射部分。

你可以拥有一个AFAMapper类,它可以为每对Source和Target进行初始化;)