Проблема создания кеша для настройки полей с помощью отражения - PullRequest
0 голосов
/ 30 октября 2019

Я пытаюсь установить большое количество полей в объекте, используя отражение. Это нормально, не беспокойтесь об этом, однако отражение стоит дорого, и после прочтения многих статей, пытающихся ускорить это, я сейчас пытаюсь создать кеш, это отлично работает для строковых переменных, но по какой-то причине он неправильно устанавливает целые числа.

Все поля выглядят примерно так

public string MyStringField = string.Empty;
public int MyIntField = 0;
public bool MyBoolField = false;

Кэш - это просто словарь имени поля и делегата действия для выполнения Set.

public static Dictionary<string, Action<SettingsClass, object>> ObjectCache;

Первоначальное заполнение кэша выполняется с использованием приведенного ниже кода

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);
}

Метод CreateSetter, который я использую для создания делегата, таков - этот бит, который я не совсем понимаю, если честно.

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>));
}

И, наконец, когда я вызываю делегата для заполнения экземпляра моего объекта, я просто использую: (элемент просто datarow)

ObjectCache[settingName].Invoke(obj, item["SettingValue"]);

Это все работает правильно, но когда я пытаюсьчтобы установить целое число, например, 12 это странное значение 92266380. Я приложил изображение окна просмотра.

enter image description here

Iпредположим, что подход, который мне понадобится, - это сохранить тип свойства в кеше и каким-то образом преобразовать его в делегат, но я не уверен, как это сделать.

Любой совет очень ценится и спасибозаранее, авансом. Если вам нужна дополнительная информация, дайте мне знать.

...