Posso ottenere l'istanza chiamante dall'interno di un metodo tramite riflessione/diagnostica?

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

  •  01-07-2019
  •  | 
  •  

Domanda

Esiste un modo tramite System.Reflection, System.Diagnostics o altro per ottenere un riferimento all'istanza effettiva che chiama un metodo statico senza passarlo al metodo stesso?

Ad esempio, qualcosa del genere

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();
    }
}

Posso ottenere il tipo utilizzando System.Diagnostics.StackTrace.GetFrames, ma esiste un modo per ottenere un riferimento all'istanza reale?

Sono consapevole dei problemi relativi alla riflessione e alla performance, nonché alle chiamate da statiche a statiche, e che questo in genere, forse anche quasi universalmente, non è il modo giusto di affrontare la questione.Parte del motivo di questa domanda è che ero curioso di sapere se fosse fattibile;stiamo attualmente trasmettendo l'istanza.

ExecuteMethod(instance)

E mi chiedevo solo se fosse possibile e se potessi ancora accedere all'istanza.

ExecuteMethod()

@SteveCooper:Non avevo considerato metodi di estensione.Qualche variazione potrebbe funzionare.

È stato utile?

Soluzione

Non credo che tu possa.Anche le classi StackTrace e StackFrame forniscono solo informazioni sui nomi, non l'accesso alle istanze.

Non sono sicuro del motivo esatto per cui vorresti farlo, ma sappi che anche se potessi farlo, probabilmente sarebbe molto lento.

Una soluzione migliore sarebbe quella di inviare l'istanza a un contesto locale del thread prima di chiamare ExecuteMethod che è possibile recuperare al suo interno o semplicemente passare l'istanza.

Altri suggerimenti

Considera l'idea di rendere il metodo un metodo di estensione.Definirlo come:

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

Si chiama così:

this.StaticExecute();

Non riesco a pensare a un modo per fare quello che vuoi fare direttamente, ma posso solo suggerire che se trovi qualcosa, fai attenzione ai metodi statici, che non ne avranno uno, e ai metodi anonimi, che avranno istanze di classi generate automaticamente, il che sarà un po' strano.

Mi chiedo se dovresti semplicemente passare l'oggetto invocante come parametro corretto.Dopotutto, a static è un suggerimento che questo metodo non dipende da nient'altro che dai suoi parametri di input.Tieni inoltre presente che questo metodo potrebbe essere complicato da testare, poiché qualsiasi codice di prova che scrivi non avrà lo stesso oggetto di chiamata del sistema in esecuzione.

Nel caso di un metodo statico che chiama il tuo metodo statico, non esiste alcuna istanza chiamante.

Trova un modo diverso per realizzare qualunque cosa tu stia cercando di fare.

Chiedi semplicemente a ExecuteMethod di prendere un oggetto.Allora hai l'istanza, qualunque cosa accada.

Sento che mi manca qualcosa, qui.Il metodo statico può essere chiamato letteralmente ovunque.Non esiste alcuna garanzia che un'istanza di classe A o di classe B venga visualizzata in qualsiasi punto dello stack di chiamate.

Deve esserci un modo migliore per realizzare qualunque cosa tu stia cercando di fare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top