2010-03-04 2 views
5

In C# 4.0, c'è un nuovo oggetto DynamicObject.C# 4.0 - Il richiamo di un metodo protetto su un oggetto dinamico chiama TryInvokeMember()?

Fornisce un "metodo magico" TryInvokeMember() che viene chiamato quando tenta di chiamare un metodo che non esiste.

http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.tryinvokemember%28VS.100%29.aspx

Quello che vorrei sapere è se TryInvokeMember() viene chiamato quando si cerca di chiamare un metodo protetto al di fuori della classe di definizione.

Sto contrastando il comportamento con PHP, che chiama il suo equivalente "metodo magico" __call() in questa situazione.

+6

Non essere una puntura, ma la prima cosa che farei in questo scenario è provare e vedere :) – spronkey

risposta

6

Quando si scrive una chiamata che invoca un metodo non accessibile (utilizzando le regole di accesso C# standard), il metodo inaccessibile non verrà chiamato e il runtime chiamerà lo TryInvokeMember (dove è possibile gestire la chiamata in qualche altro modo). Ecco un esempio, in modo che si può provare:

class Test : DynamicObject { 
    public void Foo() { 
    Console.WriteLine("Foo called"); 
    } 
    protected void Bar() { 
    Console.WriteLine("Bar called"); 
    } 

    public override bool TryInvokeMember 
     (InvokeMemberBinder binder, object[] args, out object result) { 
    Console.WriteLine("Calling: " + binder.Name); 
    return base.TryInvokeMember(binder, args, out result); 
    } 
} 

Ora, siamo in grado di creare un'istanza dell'oggetto e provare a chiamare alcuni dei suoi metodi:

dynamic d = new Test(); 
d.Foo(); // this will call 'Foo' directly (without calling 'TryInvokeMember') 
d.Bar(); // this will call 'TryInvokeMember' and then throw exception 

Quindi, se si chiama il base implementazione di TryInvokeMember, il raccoglitore dinamico C# fallirà quando si chiama un metodo inaccessibile, ma è possibile definire la propria gestione del caso in TryInvokeMember (impostando il valore result su un valore e restituendo true).

+1

Giusto per chiarire il problema. Genera un'eccezione perché si chiama un raccoglitore predefinito. Basta cambiare "return base.TryInvoke" con qualcosa come "risultato = null; return true;" per evitare l'eccezione. Probabilmente non lo intendevi, ma ora sembra che chiamare un metodo protetto risulterà sempre in un'eccezione (o è il mio creatore tecnologico di raccolta nitida?) –

+0

Tomas, sono passati anni da quando hai detto che avresti chiarito il ultima frase. Quanto dovremmo aspettare? – KMX