2013-03-28 34 views
9

is運營商如何處理DLR?「is」操作符是如何處理動態對象的?

爲了使我的問題有點更加明確,可以考慮以下特徵:

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

默認情況下,什麼樣的條件是必要的Is<T>返回true?此外,DLR是否提供任何機制來定製此行爲?

+0

你想要什麼類型的定製行爲? –

+0

@ReedCopsey,粒度ducktyping:我想能夠做一些像有一個接口:'公共接口INamed {string Name {get; }}'當我檢查'getInstance()是INamed'時,如果動態對象包含一個名爲「Name」的字符串屬性,我的自定義'DynamicMetaObject'實現將返回true。有什麼建議麼? – smartcaveman

+0

您需要自己執行檢查,可能是通過反射界面等。 –

回答

6

在運行時,dynamicobject的處理方式相同,這意味着getInstance委託人結果的運行時類型將用於執行此檢查。在這裏使用dynamic唯一的區別將會導致沒有編譯時檢查,並且動態綁定將在運行時用於對由getInstance返回的動態對象執行此檢查。

默認情況下,Is返回true需要什麼條件?

傳入的代理將需要返回一個類型,該類型在運行時與T兼容。

此外,DLR是否提供任何機制來定製此行爲?

不會。這會對C#類型使用標準規則。任何自定義行爲都需要寫入邏輯本身。

+0

因此,結果與'typeof(T)'相同。的GetType()。IsInstanceOfType(的getInstance())'? – smartcaveman

+0

@smartcaveman它更像是使用[Type.IsAssignableFrom](http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx),即:'typeof(T).IsAssignableFrom(getInstance( ).GetType())' –

+0

在這種情況下,使用'object'實際上沒有任何區別。 – jbtule

0

由於is已經是一個運行測試,沒有任何多餘的運行時綁定正在做的,其實不會有任何編譯IL差

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

的IL兩個Is<T>(Func<object> getInstance)的方法體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 

所以答案是is關鍵字不是由DLR的使用實現的,它的工作原理一樣,如果你使用的類型object

+0

那麼根本沒有編譯差異?如果它是一個DynamicObject的實例或類似的東西呢? – usr

+0

如果它是一個DynamicObject,它只有在bool是時纔是true。是的,你可以編寫代碼,編譯它,在這種情況下,兩種方式都是相同的IL。 – jbtule

+0

我不太確定。 DynamicObject被專門處理。它可以用來自定義很多行爲(想想ExpandoObject)。它也有一個TryConvert功能。另外,如果對象是python對象呢?我確定類型轉換的python規則是不同的,所以它們可能是可定製的?! – usr