2011-11-28 3 views
6

J'ai créé le Sample-Code mise en jachère:Obtenir la cible d'action

class Program { 
    static void Main(string[] args) { 
     var x = new ActionTestClass(); 
     x.ActionTest(); 
     var y = x.Act.Target; 
    } 
} 

public class ActionTestClass { 
    public Action Act; 
    public void ActionTest() { 
     this.Act = new Action(this.ActionMethod); 
    } 

    private void ActionMethod() { 
     MessageBox.Show("This is a test."); 
    } 
} 

Quand je fais sur cette voie, y sera un objet de type ActionTestClass (qui est créé pour x). Maintenant, quand je change la ligne

this.Act = new Action(this.ActionMethod); 

à

this.Act = new Action(() => MessageBox.Show("This is a test.")); 

y (la cible de l'action) sera nulle. Y at-il un moyen, que je peux obtenir la cible (dans l'exemple l'objet ActionTestClass) aussi sur la façon dont j'utilise une action anonyme?

+0

suivant Personnellement, je ne suis pas surpris que ce 'Action' ne sait rien le 'ActionTestClass' qui s'y réfère. Pourquoi le ferais-tu? – AakashM

+0

@AakashM: Dans le premier exemple, vous liez une méthode d'instance, donc 'Target' ne doit pas être nul. Cependant, cela pourrait ne pas échouer en raison de l'absence de toute variable d'instance. Je ne pense pas que vous pouvez le lier sans 'Target' en utilisant un constructeur délégué. – leppie

+0

@leppie désolé, je voulais dire le deuxième exemple - contrairement au premier exemple, pour le second 'Action' il est clair par inspection qu'il n'a rien à voir avec un objet particulier, donc je ne suis pas du tout surpris que son' Target 'est' null'. Devrais-je m'attendre à autre chose? – AakashM

Répondre

1

L'absence de Target (iow == null) implique que le délégué appelle une méthode static ou qu'aucun environnement n'a été capturé (ce n'est pas une fermeture, juste un 'pointeur de fonction').

+1

Exercice au lecteur: Comprendre pourquoi les fermetures sont les classes du pauvre en ce qui concerne la réponse ci-dessus. – leppie

0

Vous pouvez utiliser les éléments suivants:

Act.Method.DeclaringType 
+0

Quelles variables pensez-vous sont capturées dans le second exemple? – leppie

+0

Aucun, je déclarais comment le compilateur crée des fermetures en général. –

+0

Cela ne répond pas vraiment à la question alors .../o \ – leppie

0

la raison pour laquelle vous voyez la cible vide est parce que la méthode anonyme ne fait pas partie d'une classe. Si vous ouvrez votre programme dans le réflecteur, il vous montrera le code qui est généré par le compilateur, ici vous verrez le

public void ActionTest() 
    { 
     this.Act = delegate { 
      Console.WriteLine("This is a test."); 
     }; 
    } 
Questions connexes