2013-03-28 12 views
9

Wie funktioniert der Operator is in Bezug auf den DLR?Wie arbeitet der Operator "ist" mit dynamischen Objekten?

Auf meine Frage ein wenig deutlicher machen, sollten Sie die folgende Signatur:

public bool Is<T>(Func<dynamic> getInstance) 
{ 
    return getInstance() is T; 
} 

standardmäßig welchen Bedingungen für Is<T> notwendig sind true zurückzukehren? Bietet der DLR außerdem einen Mechanismus, um dieses Verhalten anzupassen?

+0

Welche Art von Anpassungsverhalten möchten Sie? –

+0

@ReedCopsey, granular ducktyping: Ich möchte in der Lage sein, etwas wie eine Schnittstelle zu tun: 'öffentliche Schnittstelle INamed {string Name {get; }} 'und wenn ich überprüfe 'getInstance() ist INamed', um meine benutzerdefinierte' DynamicMetaObject' -Implementierung zurückgeben zu lassen, wenn das dynamische Objekt eine String-Eigenschaft namens "Name" enthält. Irgendwelche Vorschläge? – smartcaveman

+0

Sie müssten die Prüfungen selbst implementieren, wahrscheinlich durch Verwendung von Reflexionen an der Schnittstelle usw. –

Antwort

6

Zur Laufzeit wird dynamic genauso behandelt wie object, was bedeutet, dass der Laufzeittyp des getInstance Delegate-Ergebnisses für diese Überprüfung verwendet wird. Der einzige Unterschied bei der Verwendung von dynamic besteht darin, dass keine Überprüfung der Kompilierzeit stattfindet und die dynamische Bindung zur Laufzeit verwendet wird, um diese Überprüfung für das von getInstance zurückgegebene dynamische Objekt durchzuführen.

Welche Bedingungen sind standardmäßig erforderlich, um True zurückzugeben?

Der übergebene Delegat muss einen Typ zurückgeben, der zur Laufzeit mit T kompatibel ist.

Darüber hinaus bietet der DLR einen Mechanismus, um dieses Verhalten anzupassen?

Nein. Dies wird die Standardregeln für C# -Typen verwenden. Jedes benutzerdefinierte Verhalten müsste in die Logik selbst geschrieben werden.

+0

Also ist das Ergebnis das gleiche wie 'typeof (T). GetType(). IsInstanceOfType (getInstance()) '? – smartcaveman

+0

@smartcaveman Es ist mehr wie mit [Type.IsAssignableFrom] (http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx), dh: 'typeof (T) .IsAssignableFrom (getInstance () .GetType()) ' –

+0

In diesem Fall gibt es keine Unterschiede zur Verwendung von' object'. – jbtule

0

is Da bereits ein Laufzeit-Test gibt es keine zusätzliche Laufzeit getan Bindung in der Tat wird es nicht sein kompilierte IL Unterschied zu

public bool Is<T>(Func<object> getInstance) 
{ 
    return getInstance() is T; 
} 

Die IL für das Verfahren Körper sowohl Is<T>(Func<object> getInstance) und Is<T>(Func<dynamic> getInstance):

.maxstack 2 
    .locals init (
     [0] bool CS$1$0000) 
    L_0000: nop 
    L_0001: ldarg.1 
    L_0002: callvirt instance !0 [mscorlib]System.Func`1<object>::Invoke() 
    L_0007: isinst !!T 
    L_000c: ldnull 
    L_000d: cgt.un 
    L_000f: stloc.0 
    L_0010: br.s L_0012 
    L_0012: ldloc.0 
    L_0013: ret 

die Antwort ist also, dass is Schlüsselwort nicht durch die Nutzung des DLR durchgeführt wird, funktioniert es das gleiche wie wenn Sie den Typ object verwenden.

+0

Also gibt es überhaupt keinen kompilierten Unterschied? Was wäre, wenn es sich um eine Instanz von DynamicObject oder etwas Ähnliches handelt? – usr

+0

Wenn es ein DynamicObject ist, ist es nur wahr, wenn bool ist. Und ja, Sie können den Code schreiben, kompilieren und beide Wege werden in diesem Fall die gleiche IL sein. – jbtule

+0

Ich bin mir da nicht so sicher. DynamicObject wird speziell behandelt. Es kann verwendet werden, um viel Verhalten anzupassen (denken Sie an ExpandoObject). Es hat auch eine TryConvert-Funktion. Was ist, wenn das Objekt ein Python-Objekt ist? Ich bin sicher, dass Python-Regeln für die Typkonvertierung unterschiedlich sind, damit sie wahrscheinlich anpassbar sind ?! – usr