[英]How do I check for type equality (is operator or x.GetType() == typeof(xType)) in IronPython?
[英]Can `typeof(T).IsAssignableFrom(x.GetType())` be safely rewritten as `x is T`?
注意:這不是“使用IsAssignableFrom和”是“C#中的關鍵字”的副本。 另一個問題是關於
typeof(T).IsAssignableFrom(type))
,其中type
不是object
而是Type
。這似乎微不足道 - 我可以聽到你說,“只需調用
x.GetType()
!” - 但是由於下面提到的與COM相關的極端情況,該調用會導致問題,這就是我要求重寫的原因。
......還是有罕見的特殊情況,兩者可能會給出不同的結果?
我偶然發現了一張表格的類型檢查:
typeof(TValue).IsAssignableFrom(value.GetType())
其中TValue
是泛型類型參數(沒有任何約束), value
是一個object
。
我不完全確定將上述內容重寫為以下是否安全:
value is TValue
據我所知,這兩個測試是相同的,但COM對象除外。 is
應該引起適當QueryInterface
,而IsAssignableFrom
可能會感到困惑,由__ComObject
RCW包裝類型和報告假陰性。
is
和IsAssignableFrom
使用之間是否還有其他差異?
在更多情況下, is
和IsAssignableFrom
返回不同的結果,而不僅僅是您為COM對象提到的結果。 對於元素類型為ElementType1和ElementType2的數組類型對,其中兩種元素類型的底層類型是相同大小但具有相反符號的整數類型,則
typeof(ElementType1[]).IsAssignableFrom(typeof(ElementType2[]))
返回true但是
new ElementType2[0] is ElementType1[]
返回false
具體來說,這包括具有這些元素類型對的數組:
byte / sbyte , short / ushort , int / uint , long / ulong
IntPtr / UIntPtr
枚舉類型和整數類型或其他枚舉類型的任何組合,只要底層類型具有相同的大小
32位進程中IntPtr / UIntPtr / int / uint的任意組合
64位進程中IntPtr / UIntPtr / long / ulong的任意組合
這是由於C#和CLR類型系統的差異,如中所述
在上面提到的所有情況下, is
和IsAssignableFrom
不同結果is
因為對於new ElementType2[0] is ElementType1[]
C#編譯器在編譯時簡單地發出False
(因為它看不到例如int []可以被強制轉換to uint []因為這些是完全不同的類型,從C#perspective),完全省略任何運行時類型檢查。 幸運的是,將數組轉換為object ((object)new ElementType2[0]) is ElementType1[]
強制編譯器發出isinst
IL指令,該指令執行運行時類型檢查,返回與IsAssignableFrom
一致的結果。 對於目標類型是泛型參數的情況也是如此,因為它的類型在編譯時是未知的,並且C#編譯器必須發出isinst
。 因此,如果您打算將IsAssignableFrom
替換is
僅在目標類型為通用參數的位置(如問題標題中所示),我相信這些差異並不適合您。
static void Main(string[] args)
{
int? bob = null;
Test(bob);
}
private static void Test<T>(T bob)
{
Console.WriteLine(bob is T);
Console.WriteLine(typeof(T).IsInstanceOfType(bob));
Console.WriteLine(typeof(T).IsAssignableFrom(bob.GetType()));
Console.ReadLine();
}
是一個例子,他們的行為略有不同(因為鮑勃是空的)。 https://stackoverflow.com/a/15853213/34092可能會引起您的興趣。
除此之外(以及您提到的其他例外),它們看起來似乎是等效的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.