I'm trying to write a generic method to wrap an SDK we're using. The SDK provides "AFElement" objects that represent our data object, and each data AFElement has a collection of "AFAttributes" that map to our data objects' properties.
I've created a generic method which uses reflection to check the object it's called for's properties and get them (if they exist) from the 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;
}
The idea is I can throw any of my data objects T at this method and it would populate them, and it works, except it's exceptionally slow.
It takes around 10 seconds to get 63 objects, 93% of the time is in this conversion method. I've heard reflection wasn't very efficient, but is is this inefficient?
Is there any other way I could do this, or a way to speed things up? Am I being stupid even trying to do something this generic?
Aucun commentaire:
Enregistrer un commentaire