Puis-je obtenir l'instance d'appel depuis une méthode via réflexion / diagnostic?

StackOverflow https://stackoverflow.com/questions/97193

  •  01-07-2019
  •  | 
  •  

Question

Existe-t-il un moyen via System.Reflection, System.Diagnostics ou autre d’obtenir une référence à l’instance qui appelle une méthode statique sans la transmettre à la méthode elle-même?

Par exemple, quelque chose dans ce sens

class A
{
    public void DoSomething()
    {
        StaticClass.ExecuteMethod();
    }
}

class B
{
    public void DoSomething()
    {
        SomeOtherClass.ExecuteMethod();
    }
}
public class SomeOtherClass
{
    public static void ExecuteMethod()
    {
        // Returns an instance of A if called from class A
        // or an instance of B if called from class B.
        object caller = getCallingInstance();
    }
}

Je peux obtenir le type à l'aide de System.Diagnostics. StackTrace.GetFrames , mais existe-t-il un moyen d'obtenir une référence à l'instance réelle?

Je suis conscient des problèmes de réflexion et de performance, ainsi que d'appels statiques à statiques, et que c'est généralement, peut-être même presque universellement, la bonne façon de procéder. Une partie de la raison de cette question est que j'étais curieux de savoir si c'était faisable; nous passons actuellement l'instance.

ExecuteMethod(instance)

Et je me demandais simplement si cela était possible et si je pouvais toujours accéder à l'instance.

ExecuteMethod()

@Steve Cooper: Je n'avais pas envisagé les méthodes d'extension. Certaines variantes pourraient fonctionner.

Était-ce utile?

La solution

Je ne crois pas que vous puissiez le faire. Même les classes StackTrace et StackFrame vous donnent simplement des informations de nommage, pas d'accès à des instances.

Je ne sais pas exactement pourquoi vous voulez faire cela, mais sachez que même si vous pouviez le faire, ce serait probablement très lent.

Une meilleure solution serait de pousser l'instance dans un contexte local de thread avant d'appeler ExecuteMethod que vous pouvez récupérer dans celui-ci ou de simplement passer l'instance.

Autres conseils

Envisagez de faire de la méthode une méthode d'extension. Définissez-le comme:

public static StaticExecute(this object instance)
{
    // Reference to 'instance'
}

Il s’appelle comme:

this.StaticExecute();

Je ne peux pas penser à un moyen de faire ce que vous voulez faire directement, mais je ne peux que suggérer que si vous trouvez quelque chose, faites attention aux méthodes statiques, qui n'en auront pas, et aux méthodes anonymes, qui aura des instances de classes auto-générées, ce qui sera un peu étrange.

Je me demande si vous devriez simplement transmettre l'objet appelant en tant que paramètre approprié. Après tout, un static est un indice que cette méthode ne dépend pas d’autre que de ses paramètres d’entrée. Notez également que cette méthode peut être une chienne à tester, car tout code de test que vous écrivez n'aura pas le même objet appelant que le système en cours d'exécution.

Dans le cas d'une méthode statique appelant votre méthode statique, il n'y a pas d'instance d'appel.

Trouvez un moyen différent d'accomplir tout ce que vous essayez de faire.

Il suffit que ExecuteMethod prenne un objet. Ensuite, vous avez l'instance quoi qu'il arrive.

Je sens que je manque quelque chose, ici. La méthode statique peut être appelée littéralement n'importe où. Rien ne garantit qu’une instance de classe A ou de classe B apparaîtra n’importe où dans la pile d’appels.

Il doit y avoir un meilleur moyen d'accomplir tout ce que vous essayez de faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top