Note that there are some explanatory texts on larger screens.

plurals
  1. POReflection.Emit code calls "base." instead of "this." on Boolean field
    primarykey
    data
    text
    <p>I have the following class A.</p> <pre><code>public class A { public string Name { get; set; } } </code></pre> <p>I need to emit a dynamic proxy using Reflection.Emit to override Equals.</p> <pre><code>// This class must be generated by Reflection.Emit. public class AProxy : A { private bool equalsHasBeenCalled; public override bool Equals(object obj) { if (this.equalsHasBeenCalled) { return base.Equals(obj); } this.equalsHasBeenCalled = true; return CaseInsensitiveComparer.Equals(this, obj); // Demo. } } </code></pre> <p>However, the actual generated code (viewed with Reflector) is:</p> <pre><code>public class AProxy : A { private bool equalsHasBeenCalled; public override bool Equals(object obj) { if (base.equalsHasBeenCalled) { return base.Equals(obj); } base.equalsHasBeenCalled = true; return CaseInsensitiveComparer.Equals(this, obj); } } </code></pre> <p>..which of course throws a System.FieldAccessException (since no such member exists). The correct is to call <em>this.equalsHasBeenCalled</em> (not base.equalsHasBeenCalled).</p> <p>I am using the Reflection.Emit add-in for Reflector to generate the code (field1 is the FieldInfo for the "equalsHasBeenCalled" field):</p> <pre><code> // Writing body gen.Emit(OpCodes.Nop); // I suspect it has to be around here. gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, field1); gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Stloc_1); gen.Emit(OpCodes.Ldloc_1); gen.Emit(OpCodes.Brtrue_S, label25); gen.Emit(OpCodes.Nop); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Call, method2); gen.Emit(OpCodes.Stloc_0); gen.Emit(OpCodes.Br_S, label42); gen.MarkLabel(label25); // ..and probably here also? gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stfld, field1); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Call, method3); gen.Emit(OpCodes.Stloc_0); gen.Emit(OpCodes.Br_S, label42); gen.MarkLabel(label42); gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ret); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload