Abgeteilt von DynamicFieldAccessor statt Reflection - schneller dynamischer Zugriff auf Felder/Properties
also es geht um folgendes:
meine software parst XAML code und erstellt daraus den entsprechenden objektgraphen (z.b. ein Window). Dabei muss ich natürlich enorm viel mit Reflection arbeiten, vor allem eben eigenschaften zuweisen per PropertyInfo.SetValue.
Leider bringt mir der beschriebene ansatz nur recht wenig, da es natürlich viele verschiedene properties sind die ich schreiben muss. (ich mache es jetzt so dass ich mir DynamicAccessor instanzen für die meist frequentierten propertys erstelle.)
ich suche eigentlich nach einem weg, properties schneller schreiben zu können als mit PropertyInfo.SetValue. deshalb wäre es natürlich schön, wenn der DynamicAccessor seinen IL code dynamisch ändern könnte, je nachdem welches property als nächstes gesetzt werden soll.
Ich benutze in meinem ORMapper eine Abwandlung hiervon:
Dynamic Code Generation vs Reflection
ich habe lediglich einen Cache eingebaut.
private static Dictionary<string, GetHandler> GetHandlerCache = new Dictionary<string, GetHandler>();
private static Dictionary<string, SetHandler> SetHandlerCache = new Dictionary<string, SetHandler>();
private static Dictionary<string, InstantiateObjectHandler> InstantiateObjectHandlerCache = new Dictionary<string, InstantiateObjectHandler>();
....
public static GetHandler CreateGetHandler(Type type, FieldInfo fieldInfo)
{
string FieldFullName = type.FullName + "." + fieldInfo.Name;
if (!GetHandlerCache.ContainsKey(FieldFullName))
{
DynamicMethod dynamicGet = CreateGetDynamicMethod(type);
ILGenerator getGenerator = dynamicGet.GetILGenerator();
getGenerator.Emit(OpCodes.Ldarg_0);
getGenerator.Emit(OpCodes.Ldfld, fieldInfo);
BoxIfNeeded(fieldInfo.FieldType, getGenerator);
getGenerator.Emit(OpCodes.Ret);
GetHandler handler = (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler));
GetHandlerCache.Add(FieldFullName, handler);
}
return GetHandlerCache[FieldFullName];
}
Durch den Cache wird nur der erste aufruf etwas langsamer.
hi,
ich denke auch, dass caching die beste lösung dafür ist. falls ich doch mal "magischen" code finden sollte melde ich mich. =)