Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8472851
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T17:11:23+00:00 2026-06-10T17:11:23+00:00

I wish to generate (emit) class that implement an Interface at run-time with C#.

  • 0

I wish to generate (emit) class that implement an Interface at run-time with C#.

I have succeeded to emit methods and properties, but I failed to emit an event.

Here is the code I wish to emit:

Namespace: TestInterfaces, Class: TestIImplementMe.

public event EventHandler SimpleEvent;

Here is the IL code generated:

.event [mscorlib]System.EventHandler SimpleEvent
{
    .addon instance void TestInterfaces.TestIImplementMe::add_SimpleEvent(class [mscorlib]System.EventHandler)
    .removeon instance void TestInterfaces.TestIImplementMe::remove_SimpleEvent(class [mscorlib]System.EventHandler)
}

.method public final hidebysig specialname newslot virtual 
    instance void add_SimpleEvent (
        class [mscorlib]System.EventHandler 'value'
    ) cil managed 
{
    // Method begins at RVA 0x330c
    // Code size 48 (0x30)
    .maxstack 3
    .locals init (
        [0] class [mscorlib]System.EventHandler,
        [1] class [mscorlib]System.EventHandler,
        [2] class [mscorlib]System.EventHandler,
        [3] bool
    )

    IL_0000: ldarg.0
    IL_0001: ldfld class [mscorlib]System.EventHandler TestInterfaces.TestIImplementMe::SimpleEvent
    IL_0006: stloc.0
    // loop start (head: IL_0007)
        IL_0007: ldloc.0
        IL_0008: stloc.1
        IL_0009: ldloc.1
        IL_000a: ldarg.1
        IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
        IL_0010: castclass [mscorlib]System.EventHandler
        IL_0015: stloc.2
        IL_0016: ldarg.0
        IL_0017: ldflda class [mscorlib]System.EventHandler TestInterfaces.TestIImplementMe::SimpleEvent
        IL_001c: ldloc.2
        IL_001d: ldloc.1
        IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&, !!0, !!0)
        IL_0023: stloc.0
        IL_0024: ldloc.0
        IL_0025: ldloc.1
        IL_0026: ceq
        IL_0028: ldc.i4.0
        IL_0029: ceq
        IL_002b: stloc.3
        IL_002c: ldloc.3
        IL_002d: brtrue.s IL_0007
    // end loop
    IL_002f: ret
} // end of method TestIImplementMe::add_SimpleEvent

.method public final hidebysig specialname newslot virtual 
    instance void remove_SimpleEvent (
        class [mscorlib]System.EventHandler 'value'
    ) cil managed 
{
    // Method begins at RVA 0x3348
    // Code size 48 (0x30)
    .maxstack 3
    .locals init (
        [0] class [mscorlib]System.EventHandler,
        [1] class [mscorlib]System.EventHandler,
        [2] class [mscorlib]System.EventHandler,
        [3] bool
    )

    IL_0000: ldarg.0
    IL_0001: ldfld class [mscorlib]System.EventHandler TestInterfaces.TestIImplementMe::SimpleEvent
    IL_0006: stloc.0
    // loop start (head: IL_0007)
        IL_0007: ldloc.0
        IL_0008: stloc.1
        IL_0009: ldloc.1
        IL_000a: ldarg.1
        IL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
        IL_0010: castclass [mscorlib]System.EventHandler
        IL_0015: stloc.2
        IL_0016: ldarg.0
        IL_0017: ldflda class [mscorlib]System.EventHandler TestInterfaces.TestIImplementMe::SimpleEvent
        IL_001c: ldloc.2
        IL_001d: ldloc.1
        IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&, !!0, !!0)
        IL_0023: stloc.0
        IL_0024: ldloc.0
        IL_0025: ldloc.1
        IL_0026: ceq
        IL_0028: ldc.i4.0
        IL_0029: ceq
        IL_002b: stloc.3
        IL_002c: ldloc.3
        IL_002d: brtrue.s IL_0007
    // end loop
    IL_002f: ret
} // end of method TestIImplementMe::remove_SimpleEvent

I managed to do all but this line:
IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0)

What is the meaning of: !!0, !!0&?

How do I call this method with IL emit?

I tried to call the method, but when I add handler:

obj.SimpleEvent += new EventHandler(obj_SimpleEvent);

I get this exception:

System.BadImageFormatException was unhandled
  Message=An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
  Source=DataBuilderAssembly
  StackTrace:
       at NewTest.add_SimpleEvent(EventHandler value)
       at TestInterfaces.Program.Main(String[] args) in D:\Dev\Private\TestInterfaces\TestInterfaces\Program.cs:line 47
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

Here is the code to emit event’s add method
where

methodName = "add_SimpleEvent";
actionHanler = typeof(Delegate).GetMethod("Combine", new Type[]{typeof(Delegate),typeof(Delegate)});
eventField = typeBuilder.DefineField(info.Name, info.EventHandlerType, FieldAttributes.Private);
compareExchange = GetGenericMethod(typeof(Interlocked), "CompareExchange");// finds the correct method to call.
// thanks to @marc, create the specific method with the correct type
compareExchange = compareExchange.MakeGenericMethod(info.EventHandlerType);

GenerateEventMethod

private static MethodBuilder GenerateEventMethod(string methodName, MethodInfo actionHanler, TypeBuilder typeBuilder, EventInfo info, FieldBuilder eventField, MethodInfo compareExchange)
{
    MethodBuilder method = typeBuilder.DefineMethod(methodName, InternalMethodsAttributes, null, new Type[] { info.EventHandlerType });
    method.DefineParameter(0, ParameterAttributes.Retval, null);
    method.DefineParameter(1, ParameterAttributes.In, "value");
    ILGenerator il = method.GetILGenerator();
    il.DeclareLocal(info.EventHandlerType);
    il.DeclareLocal(info.EventHandlerType);
    il.DeclareLocal(info.EventHandlerType);
    il.DeclareLocal(typeof (bool));

    Label loop = il.DefineLabel();

    il.Emit(OpCodes.Ldarg_0);
    il.Emit(OpCodes.Ldfld, eventField);
    il.Emit(OpCodes.Stloc_0);

    il.MarkLabel(loop);// loop start (head: IL_0007)

    il.Emit(OpCodes.Ldloc_0);
    il.Emit(OpCodes.Stloc_1);
    il.Emit(OpCodes.Ldloc_1);
    il.Emit(OpCodes.Ldarg_1);

    il.Emit(OpCodes.Call, actionHanler);
    il.Emit(OpCodes.Castclass, info.EventHandlerType);

    il.Emit(OpCodes.Stloc_2);
    il.Emit(OpCodes.Ldarg_0);

    il.Emit(OpCodes.Ldflda, eventField);

    il.Emit(OpCodes.Ldloc_2);
    il.Emit(OpCodes.Ldloc_1);

    // How to do this?
    //IL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler`1<class [mscorlib]System.ConsoleCancelEventArgs>>(!!0&, !!0, !!0)
    //il.Emit(OpCodes.Call, !!0 compareExchange(!!0&,!!0, !!0));
    il.Emit(OpCodes.Call, compareExchange);

    il.Emit(OpCodes.Stloc_0);
    il.Emit(OpCodes.Ldloc_0);
    il.Emit(OpCodes.Ldloc_1);
    il.Emit(OpCodes.Ceq);
    il.Emit(OpCodes.Ldc_I4_0);
    il.Emit(OpCodes.Ceq);
    il.Emit(OpCodes.Stloc_3);
    il.Emit(OpCodes.Ldloc_3);
    il.Emit(OpCodes.Brtrue_S, loop);
    // end loop
    il.Emit(OpCodes.Ret);

    return method;
}

GetGenericMethod (specific for this issue):

private static MethodInfo GetGenericMethod(Type type, string methodName)
{
    var q = from m in type.GetMethods()
            where m.Name == methodName && m.IsGenericMethod
            select m;
    return q.FirstOrDefault();
}

Thanks,
Ofir

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T17:11:24+00:00Added an answer on June 10, 2026 at 5:11 pm

    !!0 is the T in CompareExchange<T> (i.e. !!0 is the first (zero-based) generic type parameter), and !!0& is ref T – but all of this is just specifying the overload. The important bit is the ldflda (loads by-ref the field), ldloc.2 and ldloc.1 in the lines before that, and the fact that it returns a T.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I wish to test a function that will generate lorem ipsum text, but it
i want to put an interval ,so that it will generate each time a
I have a problem, I wish to use reflection to generate instances of one
I have several large websites that I wish to create a WIX installer for.
i have created a Makefile which i would change so, that it will generate
I have a collection of models that I wish to render in a table
I wish to generate rays from the camera through the viewing plane. In order
Given the following list of descending unique numbers (3,2,1) I wish to generate all
Given a UIImage of any dimension, I wish to generate a square icon sized
I wish to be able to generate URL variables like this: http://example.com/195yq http://example.com/195yp http://example.com/195yg

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.