Exception from DynamicMethod.CreateDelegate, almost identical MSDN example

When I call CreateDelegate (delegateType), I get System.ArgumentExceptionwhich, according to MSDN, is due to the fact that the Type delegate has the wrong number of parameters or the wrong parameter types.

The strange part of the code I'm using is almost completely copied from MSDN. My whole function:

public static void AssertRaisesEvent(Action action, object obj, string eventName, NumberOfTimes numberOfTimesRaised)
{
    eventCounter = 0;
    EventInfo eventInfo = obj.GetType().GetEvent(eventName);
    Type tDelegate = eventInfo.EventHandlerType;

    Type returnType = GetDelegateReturnType(tDelegate);
    if (returnType != typeof(void))
        throw new ApplicationException("Delegate has a return type.");

    var handler =
        new DynamicMethod("CompletedHandler",
            typeof(int),
            GetDelegateParameterTypes(tDelegate),
            obj.GetType());

    // Generate a method body. This method loads a string, calls 
    // the Show method overload that takes a string, pops the 
    // return value off the stack (because the handler has no
    // return type), and returns.
    //
    ILGenerator ilgen = handler.GetILGenerator();
    FieldInfo counterFieldInfo = typeof (AssertionHelpers).GetField("eventCounter",
                                                                    BindingFlags.NonPublic | BindingFlags.Static);
    ilgen.Emit(OpCodes.Ldfld, counterFieldInfo);
    ilgen.Emit(OpCodes.Ldc_I4, 1);
    ilgen.Emit(OpCodes.Add);
    ilgen.Emit(OpCodes.Pop);
    ilgen.Emit(OpCodes.Ret);

    // Complete the dynamic method by calling its CreateDelegate
    // method. Use the "add" accessor to add the delegate to
    // the invocation list for the event.
    //

    var delParams = GetDelegateParameterTypes(tDelegate);
    var handlerParams = handler.GetParameters();

    Delegate dEmitted = handler.CreateDelegate(tDelegate);
    eventInfo.GetAddMethod().Invoke(obj, new Object[] { dEmitted });

    ...

As you can see the comments even there. As you also see, I have delParams and handlerParams variables that have the same number of parameters of the same type.

What's going on here?

MSDN: http://msdn.microsoft.com/en-us/library/ms228976.aspx

EDIT: The im event is trying to bind to:

private NullTransaction transaction;

public delegate void CompletedEventHandler(object testParam);

internal class NullTransaction : ITransaction
{
public event CompletedEventHandler Completed;
    public void Dispose()
    {
        // no implementation
    }

    public void Complete()
    {
        // no implementation
    if(Completed != null)
            Completed.Invoke(this);
    }
}
+3
source share
1

- assert, . (handler) int , int. .

; int, "" .

.

public event EventHandler SomeEvent;

; :

Delegate dEmitted = handler.CreateDelegate(tDelegate);

, tDelegate - EventHandler. handler, int.


(); :

ilgen.Emit(OpCodes.Ldfld, counterFieldInfo); <=== should be ldsfld, by the way
ilgen.Emit(OpCodes.Ldc_I4, 1); // stack is now [counter] [1]
ilgen.Emit(OpCodes.Add); // stack is now [counter + 1]
ilgen.Emit(OpCodes.Pop); // stack is now empty
ilgen.Emit(OpCodes.Ret); // return

, , . int, , - IL.


:

var handler =
    new DynamicMethod("CompletedHandler",
        null,
        GetDelegateParameterTypes(tDelegate),
        obj.GetType());

ilgen.Emit(OpCodes.Ldsfld, counterFieldInfo);
ilgen.Emit(OpCodes.Ldc_I4_1);
ilgen.Emit(OpCodes.Add);
ilgen.Emit(OpCodes.Stsfld, counterFieldInfo);
ilgen.Emit(OpCodes.Ret);

then it can work as you plan.

Also; it is easier:

Delegate dEmitted = handler.CreateDelegate(tDelegate);
eventInfo.AddEventHandler(obj, dEmitted);
+3
source

All Articles