C # эмитт, тип значения сравнить - PullRequest
0 голосов
/ 14 февраля 2019

мой предварительный вопрос как написать оператор if

в setterBuilder , если я сравниваю новое и старое значение, есть 3 способа.

  1. используйте « op_Inequality », как пишет @DudiKeleti.
  2. используйте property.PropertyType.GetMethod («Равно» , иногда возникают ошибки,"System.NullReferenceException"
  3. использовать typeof (объект) .GetMethod ("равно" .

в чем мой вопрос.

  1. некоторый тип данных, например, int, не имеет "op_Inequality", что мне тогда делать?

  2. , если я использую typeof (объект).GetMethod , я также должен использовать модель отладки, в противном случае возникают ошибки, System.AccessViolationException: 'Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена.'

Может кто-нибудь помочь мне с проблемами?

обновление 1

я идуснимок экрана.

enter image description here

1 Ответ

0 голосов
/ 14 февраля 2019

Спасибо всем.Я получил ссылку на 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);

Я надеюсь, что мой код поможет вам.

...