I am trying to set a large number of fields in an object using reflection. This is fine, no worries with that, however reflection is costly and after reading many articles trying to speed this up, I am now trying to create a cache, this works fine for string variables, but for some reason it is not setting integers correctly.
All of the fields look something like this
public string MyStringField = string.Empty;
public int MyIntField = 0;
public bool MyBoolField = false;
The cache is simply a dictionary of the field name and an action delegate to do the Set.
public static Dictionary<string, Action<SettingsClass, object>> ObjectCache;
The initial population of the cache is done using the below code
var obj = new SettingsClass();
Type demoType = obj.GetType();
ObjectCache = new Dictionary<string, Action<SettingsClass, object>>();
foreach (FieldInfo item in demoType.GetFields())
{
Type propType = item.FieldType;
var setValue = CreateSetter<SettingsClass, object>(item);
ObjectCache.Add(item.Name, setValue);
}
The CreateSetter method I am using to create the delegate is this - this bit I do not really understand to be honest.
private static Action<S, T> CreateSetter<S, T>(FieldInfo field)
{
string methodName = field.ReflectedType.FullName + ".set_" + field.Name;
DynamicMethod setterMethod = new DynamicMethod(methodName, null, new Type[2] { typeof(S), typeof(T) }, true);
ILGenerator gen = setterMethod.GetILGenerator();
if (field.IsStatic)
{
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Stsfld, field);
}
else
{
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Stfld, field);
}
gen.Emit(OpCodes.Ret);
return (Action<S, T>)setterMethod.CreateDelegate(typeof(Action<S, T>));
}
And finally when I am invoking the delegate to populate an instance of my object I simply use: (item is simply a datarow)
ObjectCache[settingName].Invoke(obj, item["SettingValue"]);
This all works correctly, but when I try to set an integer e.g 12 it is setting to a strange value of 92266380. I have a attached an image of the watch window.
I assume the approach I will need to take is store the type of the property in the cache and somehow convert it in the delegate, but I am not sure how to do this.
Any advice is greatly appreciated and thank you in advance. If you need any more information let me know.
Aucun commentaire:
Enregistrer un commentaire