Click here to Skip to main content
15,891,976 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
After a discussion yesterday I'm playing around with the idea of a Singleton 'Notifier' class that can be subscribed to application wide. To make this more useable by allowing any type to be passed in event args, I figured generics would be a good idea. The genric TEventArgs<T> : EventArgs is set up and working fine

A generic class for the singleton is not possible as then the instance would be tied to a single type so I've got a generic method that in turn calls
protected virtual void OnNotify<T>(TEventArgs<T> e) { }

Because the class itself isn't generic, I can't figure out how to create a generic event
public event EventHandler<TEventArgs<T>> Notification;
as T isn't yet defined of course. Is there a way?

Failing that, is it possible to raise a specific event that has the type hard coded
(e.g. public event EventHandler<TEventArgs<int>> Notification)
based upon the type of T in the OnNotify method and use the e parameter?

I could be barking up the wrong tree here but I'm sure it should be possible!

Posted

1 solution

I think I got a working version of your second idea. The trick was to use event accessors. The type of the value parameter in the Dictionary should be a list - I took a shortcut so it works only for one subscriber per type :)

<br />        class TEventArgs<T> : EventArgs { public T Value { get; set; } }<br /><br />        class Test<br />        {<br />            Dictionary<Type, object> d = new Dictionary<Type,object>();<br /><br />            public event EventHandler<TEventArgs<int>> MyEvent1<br />            {<br />                add<br />                {<br />                   d.Add(typeof(int), value); <br />                }<br /><br />                remove<br />                {<br />                    d.Remove(typeof(int));<br />                }<br />            }<br /><br />            public event EventHandler<TEventArgs<string>> MyEvent2<br />            {<br />                add<br />                {<br />                    d.Add(typeof(string), value);<br />                }<br /><br />                remove<br />                {<br />                    d.Remove(typeof(string));<br />                }<br />            }<br /><br />            public void OnNotify<T>(T t)<br />            {<br />                EventHandler<TEventArgs<T>> del = (EventHandler<TEventArgs<T>> )    d[t.GetType()];<br />                del(this, new TEventArgs<T>() { Value = t });<br />            }<br />        }<br /><br />        static void Main()<br />        {<br />            Test t = new Test();<br />            t.MyEvent1 += new EventHandler<TEventArgs<int>>((sender, args) => Console.WriteLine(args.Value + 1));<br />            t.MyEvent2 += new EventHandler<TEventArgs<string>>((sender, args) => Console.WriteLine(args.Value.Trim()));<br /><br />            t.OnNotify(23);                // Prints 24<br />            t.OnNotify("Senthil Rocks  "); // Prints Senthil Rocks<br /><br />


The code inside the add and remove accessors is very similar, but the compiler doesn't like if the event declaration has a generic parameter.

 
Share this answer
 


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900