2010-05-07 12 views
7

Ho situazione in cui devo chiamare il metodo di interfaccia utilizzando la riflessione, come questoRiflessione .NET: come chiamare il metodo dell'interfaccia senza creare un'istanza?

object x = null; 
MethodInfo method = interfaceExists.GetMethod("ShutDown"); 
method.Invoke(x, new object[] { 4 }) 

Come potete vedere io non creo istanza di oggetto! E, come posso supposto, ricevo eccezione

metodo non-statico richiede un bersaglio

e domanda, posso chiamare il metodo di interfaccia utilizzando la riflessione senza creare un'istanza di interfaccia e se sì, come Riesco a farlo ?

+0

Pensateci in questo modo: cosa avrebbe effettivamente * fatto * questo metodo, se poteste invocarlo? – Aaronaught

risposta

12

Se siete assolutamente sicuri il metodo dell'interfaccia non avrà alcun impatto sullo stato dell'oggetto (e questo è generalmente un presupposto molto brutto), è possibile creare un'istanza senza chiamare il costruttore chiamando FormatterServices.GetUnitializedObject. Personalmente, raccomando vivamente di non farlo, poiché qualsiasi numero di cose brutte potrebbe accadere quando si chiama un metodo di interfaccia su un tipo non inizializzato.

+3

+1 per tecniche segrete ninja. – Will

+0

Grazie, forse ragionevolmente per me – jitm

10

Se si tratta di un metodo di istanza, è necessaria un'istanza con cui chiamare il metodo. Quindi il metodo "istanza".

I metodi di istanza possono avere dipendenze da variabili di istanza, di cui la riflessione non sarebbe a conoscenza, quindi non può garantire che un metodo di istanza non altera lo stato dell'istanza del tipo in cui è definito.

Ecco perché riceverai gli avvisi di FxCop (parafrasando qui) "Rendi questo metodo statico in quanto non altera lo stato della classe".

+0

Come posso rendere statico il metodo di interfaccia? – jitm

+0

Non è possibile avere metodi statici su un'interfaccia. Avrai bisogno di un metodo statico su una classe, se non vuoi che la classe sia usata, contrassegnala come astratta e implementando l'interfaccia, poi ne ricaverai delle sottoclassi. – Ian

+0

@jitm non puoi. Se davvero ** devi veramente fare questo, considera l'interruzione della tua interfaccia per una classe base. Ovviamente, non è possibile sovrascrivere i metodi statici della classe base, quindi è possibile che tu sia ancora fregato.Prova a fare un'altra domanda su SO (non usarlo) che spiega in dettaglio cosa stai cercando di fare e chiedi se c'è un modo migliore. – Will

4

Se il metodo non è statico, è necessario creare un'istanza di oggetto per utilizzarlo. Poiché le interfacce non possono avere metodi statici, è necessario creare un'istanza di un oggetto con l'interfaccia su di esso per eseguire il metodo.

1

Un'interfaccia non ha implementazione quindi non è possibile chiamare il suo metodo senza un'istanza di un oggetto che implementa tale interfaccia.

2

Il metodo di interfaccia non statica dovrà infine chiamare un metodo implementato su un oggetto. Se l'implementazione del metodo non esiste, non è possibile chiamare alcun metodo reale.

1

È possibile chiamare un metodo di interfaccia senza creare un'istanza? No. Le interfacce sono ad esempio membri; i membri della classe statici non sono correlati alle interfacce.

Potreste essere in grado di ottenere ciò che si desidera, fornendo un'implementazione statica dell'interfaccia,

public class MyImplementation : IMyInterface 
{ 
    public static readonly Instance = new MyImplementation(); 
    private MyImplementation() { } 
} 
// ...then your code might look like: 
MethodInfo method = typeof(IMyInterface).GetMethod("ShutDown"); 
method.Invoke(MyImplementation.Instance, new object[] { 4 }) 

Oppure si potrebbe fare un metodo di estensione:

public static class MyExtensions 
{ 
    public static void ShutDown(this IMyInterface obj, ...) { ... } 
} 
// ...then your code might look like: 
object x = null; 
MethodInfo method = typeof(MyExtensions).GetMethod("ShutDown"); 
method.Invoke(x as IMyInterface, new object[] { 4 }); 
+0

Grazie, lo so. – jitm

Problemi correlati