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 8778081
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T19:26:21+00:00 2026-06-13T19:26:21+00:00

I’ve copied the code from here: https://whathecode.wordpress.com/2012/03/26/null-checks-for-event-handlers-an-aspect-solution/ But I can’t seem to get it

  • 0

I’ve copied the code from here: https://whathecode.wordpress.com/2012/03/26/null-checks-for-event-handlers-an-aspect-solution/

But I can’t seem to get it to work when the event is within a generically typed class. I have a class defined as:

Public Class MultiKeyDictionary<TFirstKey, TSecondKey, TValue>

and the following events:

public delegate void EventDelegate(TValue value);

public delegate void ReplacedEventDelegate(TValue oldValue, TValue newValue);

public event EventDelegate Added;

public event EventDelegate Removed;

public event ReplacedEventDelegate Replaced;

But the initialisation code exceptions complaining that the type’s ContainsGenericParameters is set to true (or something similar to that).

I’ve changed the code in that link in the RuntimeInitialize method to this:

public override void RuntimeInitialize(EventInfo eventInfo) {
    base.RuntimeInitialize(eventInfo);
    Type eventType;
    MethodInfo delegateInfo = eventInfo.EventHandlerType.MethodInfoFromDelegateType();          
    ParameterExpression[] parameters = delegateInfo.GetParameters().Select(p => Expression.Parameter(p.ParameterType)).ToArray();
    if(eventInfo.EventHandlerType.ContainsGenericParameters) {
        var genericDelegate = eventInfo.EventHandlerType.GetGenericTypeDefinition();
        var genericParams = genericDelegate.GetGenericArguments();
        eventType = genericDelegate.MakeGenericType(genericParams);
    } else {
        eventType = eventInfo.EventHandlerType;
    }
    Delegate emptyDelegate = Expression.Lambda(eventType, Expression.Empty(), "EmptyDelegate", true, parameters).Compile();
    this.addEmptyEventHandler = instance => eventInfo.AddEventHandler(instance, emptyDelegate);
}

But all I get now is an ArgumentException: ParameterExpression of type ‘TValue’ cannot be used for delegate parameter of type ‘TValue’ on the line creating emptyDelegate.

  • 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-13T19:26:22+00:00Added an answer on June 13, 2026 at 7:26 pm

    As I replied earlier on my blog, the main problem here is when RuntimeInitialize() is called PostSharp doesn’t know yet with which generic arguments the class will be initialized. However when OnConstructorEntry() is called we do have this information. For more information about how PostSharp aspects work, be sure to read the documentation on Aspect lifetimes.

    In the existing code, when the aspect is created at runtime for the class (the RuntimeInitialize() method) I simply ignored the fact that the class could be generic. This was on oversight on my part. You can’t compile ‘generic’ types using Expression.Lambda, hence it is impossible to compile a common event handler which can be used by all different instantiations of the generic type.

    You need to compile this empty event handler at run time for each different instantiation of the generic type separately. This can be done in OnConstructorEntry where you can receive the instance type from the MethodExecutionArgs parameter passed by PostSharp.

    In order to know which event you need to add a handler to, you need to store EventInfo in your aspect at runtime initialization.

    [NonSerialized]
    EventInfo _event;
    

    You know which event the aspect applies to by comparing names. What follows is currently working code from OnConstructorEntry().

    Type runtimeType = args.Instance.GetType();
    EventInfo runtimeEvent =
        runtimeType.GetEvents().Where( e => e.Name == _event.Name ).First();
    
    MethodInfo delegateInfo =
        DelegateHelper.MethodInfoFromDelegateType( runtimeEvent.EventHandlerType );
    ParameterExpression[] parameters = delegateInfo
        .GetParameters()
        .Select( p => Expression.Parameter( p.ParameterType ) )
        .ToArray();
    Delegate emptyDelegate = Expression.Lambda(
        runtimeEvent.EventHandlerType, Expression.Empty(),
        "EmptyDelegate", true, parameters ).Compile();
    
    // Add the empty handler to the instance.
    MethodInfo addMethod = runtimeEvent.GetAddMethod( true );
    if ( addMethod.IsPublic )
    {
        runtimeEvent.AddEventHandler( args.Instance, emptyDelegate );
    }
    else
    {
        addMethod.Invoke( args.Instance, new object[] { emptyDelegate } );
    }
    

    This still leaves open one problem. We do not want to do all this reflection every time the type is constructed! Therefore ideally you should cache the method which adds the empty handler as previously in RuntimeInitialize(). Since the aspect code is ‘shared’ by all instantiations of the generic type (they use the same scope), you should cache for each instance type separately. E.g. using a Dictionary<Type, Action<object>>, where Type refers to the instance type and Action<object> is the method which can add the empty event handler to the instance.

    This is exactly the implementation I now use in my library, of which you can find the updated version on github. As you will see I use a CachedDictionary class, which handles most of the caching logic already for you since it is such a common scenario. The previously failing unit test now succeeds.

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

Sidebar

Related Questions

I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
For some reason, after submitting a string like this Jack’s Spindle from a text
I have this code to decode numeric html entities to the UTF8 equivalent character.
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I have a text area in my form which accepts all possible characters from
Does anyone know how can I replace this 2 symbol below from the string
I am currently running into a problem where an element is coming back from

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.