2009-07-10 2 views
8

Angesichts der neuen dynamischen Unterstützung in C# 4 ist es möglich, eine Klasse so zu schreiben, dass eine Methode aufgerufen wird Instanz und diese Methode ist nicht vorhanden, wird der Versand an eine andere Methode übergeben? Dies könnte etwa so aussehen:Behandeln einer C# -Methode, die nicht für ein dynamisches Objekt definiert ist (aka respond_to/method_missing)

public class Apple : ... { 
    // ... 

    private ... MethodMissing(string name, ...) { 
    if (name == "TurnIntoOrange") { 
     // do something 
    } 
    } 
} 

dynamic d = new Apple(); 
d.TurnIntoOrange();  // Not actually defined on Apple; will pass to MethodMissing. 

Andere Sprachen nennen würde diese „method_missing Unterstützung“, unter dem allgemeineren Begriff des metaprogramming. Ich bin nicht sicher, was C# das spezifisch nennt. Aber ist es möglich?

Antwort

17

Absolut. Entweder implementieren Sie IDynamicMetaObjectProvider oder leiten Sie von DynamicObject für eine viel einfachere Route. Sehen Sie die DLR documentation für einige gute Beispiele.

Hier ist ein kurzes Beispiel DynamicObject:

using System; 
using System.Dynamic; 

public class MyDynamic : DynamicObject 
{ 
    public override bool TryInvokeMember 
     (InvokeMemberBinder binder, 
     object[] args, 
     out object result) 
    { 
     Console.WriteLine("I would have invoked: {0}", 
          binder.Name); 
     result = "dummy"; 
     return true; 
    } 

    public string NormalMethod() 
    { 
     Console.WriteLine("In NormalMethod"); 
     return "normal"; 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     dynamic d = new MyDynamic(); 
     Console.WriteLine(d.HelloWorld()); 
     Console.WriteLine(d.NormalMethod()); 
    } 
} 

<plug>

Ich habe ein größeres Beispiel DynamicObject im 2nd edition of C# in Depth aber ich habe noch nicht IDyamicMetaObjectProvider umgesetzt. Ich werde dies vor der Veröffentlichung des Buches tun, aber die frühe Zugriffsversion hat nur das DynamicObject Beispiel im Moment. BTW, wenn Sie es heute kaufen, ist es der halbe Preis - verwenden Sie den Code twtr0711. Ich werde diese Antwort bearbeiten später auf, dass etwas zu entfernen :)

</plug>

+0

Wow, danke Jon! –

+1

Ich habe darauf in meinem Titel angespielt, aber habe es nicht direkt im Körper gefragt: Gibt es eine ähnliche Überschreibung, die ich verwenden würde, um eine "Antworten" -Methode nachzuahmen? Ich sehe, dass ich das Ergebnis von TryInvokeMember überprüfen kann, aber das kann unerwünschte Nebenwirkungen haben. –

+0

Nein, ich glaube nicht, dass es eine Möglichkeit gibt, nach einer dynamischen Methode zu fragen, ob sie mit irgendetwas umgehen wird - obwohl Sie GetDynamicMemberNames als Ausgangspunkt verwenden könnten. –

Verwandte Themen