簡體   English   中英

可以`typeof(T).IsAssignableFrom(x.GetType())`安全地重寫為`x is T`?

[英]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包裝類型和報告假陰性。

isIsAssignableFrom使用之間是否還有其他差異?

在更多情況下, isIsAssignableFrom返回不同的結果,而不僅僅是您為COM對象提到的結果。 對於元素類型為ElementType1ElementType2的數組類型對,其中兩種元素類型的底層類型是相同大小但具有相反符號的整數類型,則

typeof(ElementType1[]).IsAssignableFrom(typeof(ElementType2[]))返回true但是

new ElementType2[0] is ElementType1[]返回false

具體來說,這包括具有這些元素類型對的數組:

  • byte / sbyteshort / ushortint / uintlong / ulong

  • IntPtr / UIntPtr

  • 枚舉類型和整數類型或其他枚舉類型的任何組合,只要底層類型具有相同的大小

  • 32位進程中IntPtr / UIntPtr / int / uint的任意組合

  • 64位進程中IntPtr / UIntPtr / long / ulong的任意組合

這是由於C#和CLR類型系統的差異,如中所述

在上面提到的所有情況下, isIsAssignableFrom不同結果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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM