2010-01-08 11 views
0

J'essaie de mettre en œuvre le modèle d'observateur avec une légère torsion, le sujet et l'observateur sont de la même classe. Par exemple,Modèle d'observateur C# utilisant des génériques

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 } 

} 

Cela devrait fonctionner correctement. Maintenant, je veux supprimer la pénalité de performance imposée par la boxe et le déballage chaque fois que j'ai un événement de mise à jour, donc je supprime l'implémentation basée sur "objet" et j'essaie d'utiliser des génériques. Par exemple,

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 
     } 

} 

Cela ne fonctionne pas, parce que j'ai un EventHandler, il peut être soit Tin ou Tout, mais pas les deux. Comment puis-je contourner cela ? Toutes les autres suggestions pour changer de design sont les bienvenues. Merci beaucoup d'avoir lu ceci et j'espère que c'est assez clair pour comprendre la question.

+2

Puisque vous n'utilisez aucun type de valeur, il n'y a pas de boxe dans ce code. – SLaks

+0

ok, cela peut être plus basique alors, quand je reçois l'objet dans une fonction je vais devoir le lancer à mon type, n'est-ce pas une pénalité de performance avec ça? – fadini

+0

Les événements implémentent déjà le modèle d'observateur. Vous pouvez attacher n'importe quel délégué à l'événement pour l'afficher. L'événement peut porter toute information que vous aimez. Quel est le problème? –

Répondre

2

Changer votre gestionnaire d'événements aussi:

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

public event UpdateHandler<Tin> UpdateEvent; 
+0

Si je vous comprends bien, j'ai essayé cela, et ça ne marche pas? – fadini

+0

Ok, la syntaxe peut être un peu éteinte, mais vous pouvez utiliser cette approche. Que passez-vous dans ce gestionnaire? La référence de l'étain ou le TOut, ou les deux? Le point est que les génériques dans le délégué peuvent réduire le problème de boxe/unboxing. –

+0

Je passe à l'étain et je l'attache. Ensuite, j'appelle Tout. Mais il n'y a pas de boxe/unboxing dans ce cas? – fadini

0

Découvrez this question et réponses. C'est une très bonne implémentation de pub/sub avec des génériques fortement typés.

+0

Je vais jeter un coup d'oeil, il me faudra parfois analyser tout ça. Merci – fadini