注意:这不是"Use of IsAssignableFrom and “is” keyword in C#"的副本。另一个问题是关于typeof(T).IsAssignableFrom(type))
,其中type
不是object
而是Type
。
这似乎微不足道-我能听到你说,“打电话就行了!”-但由于下面提到的与com相关的角落案例,该调用会导致问题,这就是我询问重写的原因。
……还是有罕见的特殊情况,两种情况可能会产生不同的结果?
我偶然发现一张表格的类型检查表:
typeof(TValue).IsAssignableFrom(value.GetType())
其中
x.GetType()
是一个泛型类型参数(没有任何约束),而TValue
是一个value
。我不完全确定将上述内容简单改写为:
value is TValue
据我目前所知,除了com对象之外,这两个测试是等价的。
object
应该触发一个正确的is
,而QueryInterface
可能会被IsAssignableFrom
rcw包装类型混淆,并报告一个假阴性。__ComObject
与所示的使用is
之间是否有其他差异? 最佳答案
还有更多的情况是is
和IsAssignableFrom
返回不同的结果,而不仅仅是您为com对象提到的结果。对于元素类型为ElementType1和ElementType2的数组类型对,如果两种元素类型的底层类型都是相同大小但有相反符号的整数类型,则typeof(ElementType1[]).IsAssignableFrom(typeof(ElementType2[]))
返回true,但new ElementType2[0] is ElementType1[]
返回false
具体来说,这包括具有以下元素类型对的数组:
字节/字节,短/短,整型/单型,长/长
输入/输出
枚举类型与整数类型或其他枚举类型的任意组合,只要底层类型的大小相同
32位进程中intptr/uintptr/int/uint的任意组合
64位进程中intptr/uintptr/long/ulong的任意组合
这是由于C和CLR的类型系统不同,如中所述
Why does my C# array lose type sign information when cast to object?
Why does “int[] is uint[] == true” in C#
Why is covariance of value-typed arrays inconsistent?
在上述所有情况下,is
和IsAssignableFrom
的不同结果都是由于编译器在编译时发出new ElementType2[0] is ElementType1[]
的结果(因为它看不到将int[]转换为uint[]的方法,因为这些类型从c角度来看完全不同),完全忽略了任何运行时类型检查。幸运的是,将数组转换为objectFalse
会强制编译器发出((object)new ElementType2[0]) is ElementType1[]
il指令,该指令执行运行时类型检查,返回与isinst
一致的结果。对于目标类型是泛型参数的情况也是如此,因为它的类型在编译时是未知的,并且C编译器必须发出IsAssignableFrom
。因此,如果您打算仅在目标类型是泛型参数(如问题标题中所建议的那样)的地方将isinst
替换为IsAssignableFrom
,那么我相信这些差异并不适合您。