2011-08-12 1 views
14

Je viens de réaliser des événements statiques existent - et je suis curieux de savoir comment les gens les utilisent. Je me demande comment la comparaison relative résiste aux méthodes statiques et aux méthodes d'instance. Par exemple, une méthode statique est fondamentalement une fonction globale. Mais j'ai toujours associé des événements avec instances d'objets et j'ai du mal à les penser au niveau global.Comment les événements statiques se comparent-ils aux événements non statiques en C#?

Voici un code pour désigner si elle aide une explication:

void Main() 
{ 
    var c1 = new C1(); 
    c1.E1 +=() => Console.WriteLine ("E1"); 
    C1.E2 +=() => Console.WriteLine ("E2"); 
    c1.F1(); 
} 

// <<delegate>>+D() 
public delegate void D(); 

// +<<event>>E1 
// +<<class>><<event>>E2 
// +F() 
//  <<does>> 
//   <<fire>>E1 
//   <<fire>>E2 
public class C1 
{ 
    public void F1() 
    { 
     OnE1(); 
     OnE2(); 
    } 
    public event D E1; 
    private void OnE1() 
    { 
     if(E1 != null) 
     { 
      E1(); 
     } 
    } 
    static public event D E2; 
    static private void OnE2() 
    { 
     if(E2 != null) 
     { 
      E2(); 
     } 
    } 
} 

Répondre

14

Une grande partie de la POO peut être considérée en termes de passage de message.

Un appel de méthode est un message de l'appelant à l'appelé (portant les paramètres) et un message de retour avec la valeur de retour.

Un événement est un message de la source à l'abonné. Il y a donc potentiellement deux instances impliquées, celle qui envoie le message et celle qui le reçoit.

Avec un événement statique, il n'y a pas d'instance d'envoi (juste un type, qui peut être ou non une classe). Il peut toujours y avoir une instance de destinataire codée comme cible du délégué.

1

membres statiques ne sont pas « globale », ils sont tout simplement les membres de la classe, pas de instances de classe. Cela est aussi vrai pour les événements que pour les méthodes, les propriétés, les champs, etc.

Je ne peux pas donner un exemple d'utilisation d'un événement statique, car je ne trouve généralement pas les membres statiques utiles dans la plupart des cas . (Ils ont tendance à faire allusion à des anti-modèles, comme Singleton.)

+0

donc la liste des abonnés est trop au niveau de la classe? cela signifie-t-il que l'abonnement multiple en même temps entraînera de mauvaises choses? –

+0

L'implémentation par défaut pour les événements statiques utilisera 'Interlocked.CompareExchange', ce qui signifie que dans le cas d'une course, l'un des threads ne sera pas abonné. – cdhowie

+0

@cdhowie: Ce serait une utilisation très stupide de 'Interlocked.CompareExchange'. Normalement, compare-and-swap est associé à une boucle de réessai. –

3

Si vous n'êtes pas familier avec les méthodes statiques

Vous êtes probablement déjà familiers avec les méthodes statiques. Au cas où vous ne l'êtes pas, une différence facile à comprendre est que vous n'avez pas besoin de créer une instance d'un objet pour utiliser une méthode statique, mais vous devez créer une instance d'un objet pour appeler un non-objet. méthode statique.

Un bon exemple est les classes System.IO.Directory et System.IO.DirectoryInfo.

La classe Directory offre des méthodes statiques, contrairement à la classe DirectoryInfo.

Deux articles les décrivent ici pour que vous puissiez voir la différence par vous-même.

http://visualcsharptutorials.com/2011/01/system-io-directory-class/

http://visualcsharptutorials.com/2011/01/system-io-directoryinfo-class/

maintenant à statique événements ...

Cependant, les événements statiques sont rarement vus dans la nature. Il y a très peu de cas où je peux penser opf où je voudrais en utiliser un, mais il y a un article de CodeProject qui montre une utilisation potentielle.

http://www.codeproject.com/KB/cs/staticevent.aspx

La clé pensée ici est tirée de l'explication (gras ajouté par moi de signaler le texte pertinent):

Nous avons vu cette propriété comme un objet distinct et nous avons fait en sorte que il est seulement une instance à la fois. Et toutes les transactions savaient où le trouver en cas de besoin. Il y a une différence de bien. Les transactions n'auront pas besoin de connaître les changements qui se produisent sur le taux de change, ils utiliseront plutôt la dernière valeur modifiée au moment où ils l'utilisent en demandant la valeur actuelle.Cela ne suffit pas lorsque, par exemple, nous voulons mettre en œuvre une application où l'interface utilisateur réagit immédiatement sur les changements dans les caractéristiques de l'interface utilisateur comme la police, comme si elle doit arriver à en temps réel. Il serait très facile si nous pouvions avoir une propriété statique dans la classe police appelée currentFont et une méthode statique pour changer cette valeur et un événement statique à toutes les instances pour leur faire savoir quand ils ont besoin de mettre à jour leur apparence.

En tant que développeurs .NET, nous sommes formés pour travailler avec un modèle déconnecté. Pensez à ADO.NET par rapport à ADO classique. Dans une application VB6, vous pouvez utiliser des contrôles de données qui permettent les fonctionnalités suivantes: Si vous exécutiez l'application sur votre PC, les données de votre grille se mettraient à jour lorsqu'une personne sur un autre PC modifierait les données.

Ce n'est pas quelque chose que les développeurs .NET sont habitués. Nous sommes très habitués au modèle déconnecté. Les événements statiques permettent une expérience plus "connectée". (Même si cette expérience est quelque chose que nous ne sommes pas habitués à plus.)

+0

merci pour les détails et les références utiles –

2

pour un aperçu vérifier ce lien http://www.codeproject.com/KB/cs/staticevent.aspx

événement statique peut être utilisé

  • lorsqu'aucune instance existe
  • pour faire un événement de multidiffusion pour toutes les instances existantes ...
  • lorsque vous avez une classe statique qui peut déclencher des événements ...

mais il faut les utiliser avec cuation ... voir la discussion http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/2ac862f346b24a15/8420fbd9294ab12a%238420fbd9294ab12a?sa=X&oi=groupsr&start=1&num=2

plus d'info

http://msdn.microsoft.com/en-us/library/8627sbea.aspx
http://dylanbeattie.blogspot.com/2008/05/firing-static-events-from-instance.html
http://www.nivisec.com/2008/09/static-events-dont-release.html

45

Méfiez-vous des événements statiques. Souvenez-vous que lorsqu'un objet est abonné à un événement, une référence à cet objet est conservée par l'éditeur de l'événement. Cela signifie que vous devez faire très attention à vous désabonner explicitement des événements statiques car ils garderont l'abonné en vie pour toujours, c'est-à-dire que vous risquez de vous retrouver avec l'équivalent managé d'une fuite de mémoire.

+0

c'est très bon à savoir - merci –

+2

Bon point. Dans certains cas, cependant, cela peut ne pas poser de problème. Parfois, le gestionnaire peut être statique aussi. Ou il peut vivre sur un singleton. –

+4

@TheDag: Bien sûr, ou parfois l'objet (s) abonné existe tout au long de la vie de votre application. Le problème est que vous devez maintenant * réfléchir * à ce sujet chaque fois que vous vous abonnez à cet événement statique. Cela ajoute des frais généraux et tout le monde ne se rendra pas compte de ce qui se passe. –

Questions connexes