0

my preview question how to write a if statement

in setterBuilder statement, if i compare new value and old value , there are 3 ways .

  1. use "op_Inequality" as @DudiKeleti writes.
  2. use property.PropertyType.GetMethod("Equals" , sometimes there are errors , "System.NullReferenceException"
  3. use typeof(object).GetMethod("Equals" .

what's my question.

  1. some data type , for example , int , doesn't has "op_Inequality" , what should i do then ?

  2. if i use typeof(object).GetMethod , i should alse use debug model ,otherwise, there are errors , System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

can somebody help me with the problems ?

update 1

i got a screen-snap .

enter image description here

goldii
  • 242
  • 2
  • 18
  • It's really hard to say anything useful, because your question asks many things but without many details. From your screenshot, it looks like you're trying to invoke `object.Equals` on an `int`. Obviously that won't work, you'll have to call `int.Equals(int)` (a different method). If you want to compare ints, [use ceq](https://sharplab.io/#v2:C4LglgNgNAJiDUAfAAgBgATIIwG4CwAUMgMyYBM6AwugN6HoOanIAs6AsgBRgB2w6AQyjpe/AEYBKWvUayxAe3kR0/ALyD0q9WPwFZAX0L6gA===). – canton7 Feb 14 '19 at 09:05
  • If you want to compare any two values, regardless of their type, then in C# you would write `EqualityComparer.Default.Equals(a, b)`, which compiles [to this IL](https://sharplab.io/#v2:C4LglgNgNAJiDUAfAAgBgATIIwG4CwAUGplgCz5EDMmATOgMLoDeh6bm1yp6AsgDwAVAHwAKAegCGUdOIBGASmat2K2QHs1EdMHQBedAFEAjgFcJEMMACe9NQFsADhIBOAU2eChAOgAirgGYSJhDAXsZmEADOIlLoChQqAL6EiUA). Maybe that's what you're after? It's hard to say from your question. – canton7 Feb 14 '19 at 09:08
  • @canton7 thanks for answer . i have solved it . i will post the answer. – goldii Feb 14 '19 at 09:33
  • The general, all-catching, answer to this question would be "act as a compiler". The compiler has special-casing for a lot of things. Since there are separate instructions for comparing basic values, such as ints, then no call has to be made, a simple "load the values onto the stack and branch on X" can be emitted. The problem is that you need to be aware of all these things. Writing *general purpose* code generation is **hard**. – Lasse V. Karlsen Feb 14 '19 at 10:03

1 Answers1

0

Thanks everyone. I got a reference to EntityProxyFactory. It's helpful and my code is below.

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

I hope my code will help you.

Aars93
  • 379
  • 4
  • 10
goldii
  • 242
  • 2
  • 18