views:

275

answers:

2

I am trying to implement the observer pattern with a slight twist, the Subject and Observer are the same class. For example,

class myclass
{ 
  public delegate void UpdateHandler(object sender);

  public event UpdateHandler UpdateEvent;

  public Attach(myclass obj){ // use delegate to attach update function of obj}

  public Update(object sender){ // do something with sender}

  public Notify() { // use UpdateEvent to update all attached obj's }

}

This should work fine. Now I want to remove the performance penalty imposed by boxing and unboxing everytime i have an update event, thus I remove the "object" based implementation and am trying to use generics. For example,

class myclass<Tin, Tout>
{ 
  public delegate void UpdateHandler(Tout sender);

  public event UpdateHandler UpdateEvent;

  public Attach(myclass<Tin,Tout> obj)
      { // use delegate to attach update function of obj}

  public Update(Tin sender){ // do something with sender}

  public Notify() 
      { // use UpdateEvent to update all attached obj's 
        // but now we have to send Tout 
      }

}

This does not work, because I have one EventHandler, it can either be Tin or Tout, but not both. How do I get around this ? Any other suggestions to change design also welcome. Thanks very much for reading this and I hope this is clear enough to understand the question.

+2  A: 

Hey,

Change your event handler too:

public delegate void UpdateHandler<Tin>(Tin sender); 

public event UpdateHandler<Tin> UpdateEvent; 
Brian
If i understand you correctly, I tried this, and it doesnt work ?
fadini
Ok, the syntax may be a little off, but you can use this approach. What are you passing into this handler? The Tin reference or the TOut, or both? The point is that the generics in the delegate can reduce the boxing/unboxing issue.
Brian
I am passing in Tin, and attaching it. Then I am calling Tout. But there is no boxing/unboxing in this case ?
fadini
If you are using a generic handler, there would be no boxing occuring because the delegate is generic. OK so the signature should be correct, but i'm not sure what you mean by you are calling TOut; what I was asking is strictly for this UpdateEvent. Do you mean TOut gets added to the event argument? Or should TIn be the source for the update event delegate?
Brian
Sorry for being unclear. I attach the Update(Tin sender) method to the event. Then I call the event using UpdateEvent(someObj) defined as Tout someObj. This causes a problem because they are in declared in the same class. Thank you for going through the effort.
fadini
No problem, it has been a long week :-). I see what you say... That will definitely be a problem. Either 1) just use one generic definition since they are the same type (myclass<T>), 2) you will have the separate the two processes (manually invoking both methods calls) which is probably not likely, 3) pass in TIn object and TOut object into Update, or 4) use an event to request the instance of TOut (check out my blog about this: http://tinyurl.com/yjd2mb2). Let me know if any are viable.
Brian
A: 

Check out this question and responses. It is a very good implementation of pub/sub with strongly-typed generics.

Jesse C. Slicer
I will take a look, it will take me sometime to parse all that. THanks
fadini