There are more cases where is and IsAssignableFrom return different results, and not just the ones you specified for COM objects. For a pair of array types with elements of type ElementType1 and ElementType2, where the underlying types of both types of elements are integer types of the same size, but with the opposite signature, then
typeof(ElementType1[]).IsAssignableFrom(typeof(ElementType2[])) returns true , but
new ElementType2[0] is ElementType1[] returns false
In particular, this includes arrays with these pairs of their element types:
byte / sbyte, short / ushort, int / uint, long / ulong
IntPtr / UIntPtr
any combination of an enum type and an integer type or another type of enum if the types of linings are the same size
any combination of IntPtr / UIntPtr / int / uint in a 32-bit process
any combination of IntPtr / UIntPtr / long / ulong in a 64-bit process
This is due to differences in the C # and CLR type system, as described in
The different results of is and IsAssignableFrom in all the cases mentioned above follow from the fact that for new ElementType2[0] is ElementType1[] , the C # compiler simply emits False at compile time (since it does not see the path, for example, for int [], be ported to uint [], since they are completely different types from the point of view of C #), completely excluding runtime type checks. Fortunately, casting an array to an object ((object)new ElementType2[0]) is ElementType1[] causes the compiler to generate the isinst IL command, which performs a runtime type check that returns results matching IsAssignableFrom . This is also true in cases where the target type is a common parameter, because its type is unknown at compile time, and the C # compiler must emit isinst . Therefore, if you intend to replace IsAssignableFrom with is only in those places where the target type is a common parameter (as suggested in the question heading), I believe that these differences are not for you.
source share