C# эмитт, тип значения сравнить
Мой предварительный вопрос, как написать заявление if
в заявлении setterBuilder, если я сравниваю новое значение и старое значение, есть 3 способа.
- используйте " op_Inequality ", как пишет @DudiKeleti.
- использовать property.PropertyType.GetMethod("Равно", иногда возникают ошибки "System.NullReferenceException"
- используйте typeof(object).GetMethod("Equals").
в чем мой вопрос
некоторый тип данных, например, int, не имеет "op_Inequality", что мне тогда делать?
если я использую typeof (object).GetMethod, я должен также использовать отладочную модель, в противном случае возникают ошибки, System.AccessViolationException: 'Попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена.
кто-нибудь может мне помочь с проблемами?
обновление 1
я получил снимок экрана.
1 ответ
Спасибо всем. Я получил ссылку на EntityProxyFactory. Это полезно, и мой код ниже.
Label exitSet = setIl.DefineLabel();
MethodInfo op_inequality = propertyType.GetMethod("op_Inequality", new Type[] { propertyType, propertyType });
if (op_inequality != null)
{
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldfld, fb);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Call, op_inequality);
setIl.Emit(OpCodes.Brfalse_S, exitSet);
}
else
{
// Use object inequality
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldfld, fb);
if (propertyType.IsValueType)
{
setIl.Emit(OpCodes.Box, propertyType);
}
setIl.Emit(OpCodes.Ldarg_1);
if (propertyType.IsValueType)
{
setIl.Emit(OpCodes.Box, propertyType);
}
setIl.Emit(OpCodes.Call, EqualsMethod);
setIl.Emit(OpCodes.Brtrue_S, exitSet);
}
setIl.Emit(OpCodes.Ldarg_0); // load string literal
setIl.Emit(OpCodes.Ldarg_1); // value
//-----------------important---------
if (propertyType.IsValueType)
{
setIl.Emit(OpCodes.Box, propertyType);
}
setIl.Emit(OpCodes.Ldstr, property.Name);
var parentType = tb.BaseType;
//if (parentType == null)
// throw new Exception($"Interface {tb.Name} should be inherited from \"IDbEntity\". ");
var m = parentType.GetMethod("ValueChanged", BindingFlags.Instance | BindingFlags.NonPublic);
setIl.Emit(OpCodes.Call, m);
Я надеюсь, что мой код поможет вам.