2011-08-06 5 views
-4

Dans le code suivant, fait le point ptrcall ...pointeur sur les méthodes en C# délégués

  • 2 places sur le tas avec des méthodes obj.callMe et obj1.callMe; ou ...
  • à 1 place qui contient les deux méthodes obj.callMe, obj1.callMe à l'intérieur de celle-ci?

    public delegate void CallEveryOne(); 
    
    private void Form1_Load(object sender, EventArgs e) 
    { 
    
    public CallEveryOne ptrcall=null; 
    
    public Form2 obj = new Form2(); 
    public Form3 obj1 = new Form3(); 
    
        obj.Show(); 
        obj1.Show(); 
    
        ptrcall += obj.CallMe; 
        ptrcall += obj1.CallMe; 
    } 
    
+7

Donne du sens à cette question. –

+0

Parlez comme Yoda! – Mrchief

+0

Mon babblefish vient de mourir. – Amy

Répondre

4

ptrcall est, comme essentiellement tous les délégués de .NET 2.0 en avant, un délégué de multidiffusion. Autrement dit, il conserve sa propre liste interne de méthodes auxquelles il se réfère. MSDN a ceci à dire sur MulticastDelegate:

Représente un délégué de multidiffusion; c'est-à-dire, un délégué qui peut avoir plusieurs éléments dans sa liste d'appel.   (Souligné par moi.)

Ainsi, dans votre terminologie, la réponse est plus probable que le point ptrcall 2 place sur tas.

Mais pourquoi ce détail d'implémentation est-il important?


P.S .: Vous pouvez appeler ptrcall.GetInvocationList() et voir ce que vous obtenez en retour. Je vous recommande seulement cela pour jouer et apprendre à mieux connaître les délégués; ne le faites pas dans le code de production à moins que vous ayez réellement à.

+0

si possible un délégué point à 2place dans un temps? –

+0

Oui, c'est exactement ce que votre code fait, et ce que MulticastDelegate offre. Si vous appelez le délégué, * both * 'obj.CallMe' et' obj1.CallMe' seront invoqués. – stakx

+0

merci stakx pour modifier ma question et réponse rapide –

0

Je suppose que vous voulez savoir ceci pour interop avec coe non géré? Ptrcall stocke la référence à l'instance d'objet de type CallEveryOne (qui dérive du type MulticastDelegate). Cet objet contient (entre autres) un tableau interne avec des informations sur chaque méthode ajoutée à ce délégué, mais vous n'êtes pas censé l'utiliser directement. Si vous avez besoin de pointeurs vers des méthodes abonnées, utilisez ptrcall.GetInvocationList() pour obtenir la liste des méthodes et System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate() pour les convertir en pointeurs.

+0

Votre réponse est fondamentalement correcte, @Nuf. Mais je trouve votre utilisation de la terminologie telle que _ "ptrcall points to ..." _ problématique. 'ptrcall' est ** pas ** un * pointeur *! Je pense que les gens qui sont relativement nouveaux.NET ou C# devrait être encouragé à se familiariser avec les bases de la valeur et des types de référence le plus tôt possible et cesser de penser en termes de détails de mise en œuvre (@ Mehdi utilise le terme _ "tas"). des pointeurs, rarement utilisés en C#). Voir par exemple [ces articles de blog par Eric Lippert] (http://blogs.msdn.com/b/ericlippert/archive/tags/memory+management/). – stakx

+0

@stakx: Bien sûr, ptrcall n'est pas un ** pointeur, c'est une variable qui contient ** référence ** à l'objet. Je ne sais pas, ce mot "points" implique que ptrcall soit un pointeur (ce qui n'est pas le cas), mais j'ai quand même modifié ma réponse pour (espérons-le) éviter toute confusion. – Nuf