public sealed override bool IsAssignableFrom(Type c) { if (c == null) { return(false); } if (object.ReferenceEquals(c, this)) { return(true); } c = c.UnderlyingSystemType; Type typeInfo = c; RuntimeTypeInfo toTypeInfo = this; if (typeInfo == null || !typeInfo.IsRuntimeImplemented()) { return(false); // Desktop compat: If typeInfo is null, or implemented by a different Reflection implementation, return "false." } RuntimeTypeInfo fromTypeInfo = typeInfo.CastToRuntimeTypeInfo(); if (toTypeInfo.Equals(fromTypeInfo)) { return(true); } RuntimeTypeHandle toTypeHandle = toTypeInfo.InternalTypeHandleIfAvailable; RuntimeTypeHandle fromTypeHandle = fromTypeInfo.InternalTypeHandleIfAvailable; bool haveTypeHandles = !(toTypeHandle.IsNull() || fromTypeHandle.IsNull()); if (haveTypeHandles) { // If both types have type handles, let MRT handle this. It's not dependent on metadata. if (ReflectionCoreExecution.ExecutionEnvironment.IsAssignableFrom(toTypeHandle, fromTypeHandle)) { return(true); } // Runtime IsAssignableFrom does not handle casts from generic type definitions: always returns false. For those, we fall through to the // managed implementation. For everyone else, return "false". // // Runtime IsAssignableFrom does not handle pointer -> UIntPtr cast. if (!(fromTypeInfo.IsGenericTypeDefinition || fromTypeInfo.IsPointer)) { return(false); } } // If we got here, the types are open, or reduced away, or otherwise lacking in type handles. Perform the IsAssignability check in managed code. return(Assignability.IsAssignableFrom(this, typeInfo)); }
public sealed override bool IsAssignableFrom(TypeInfo typeInfo) { RuntimeTypeInfo toTypeInfo = this; RuntimeTypeInfo fromTypeInfo = typeInfo as RuntimeTypeInfo; if (fromTypeInfo == null) { return(false); // Desktop compat: If typeInfo is null, or implemented by a different Reflection implementation, return "false." } if (toTypeInfo.ReflectionDomain != fromTypeInfo.ReflectionDomain) { return(false); } if (toTypeInfo.Equals(fromTypeInfo)) { return(true); } RuntimeTypeHandle toTypeHandle = default(RuntimeTypeHandle); RuntimeTypeHandle fromTypeHandle = default(RuntimeTypeHandle); bool haveTypeHandles = toTypeInfo.RuntimeType.InternalTryGetTypeHandle(out toTypeHandle) && fromTypeInfo.RuntimeType.InternalTryGetTypeHandle(out fromTypeHandle); if (haveTypeHandles) { // If both types have type handles, let MRT handle this. It's not dependent on metadata. if (ReflectionCoreExecution.ExecutionEnvironment.IsAssignableFrom(toTypeHandle, fromTypeHandle)) { return(true); } // Runtime IsAssignableFrom does not handle casts from generic type definitions: always returns false. For those, we fall through to the // managed implementation. For everyone else, return "false". // // Runtime IsAssignableFrom does not handle pointer -> UIntPtr cast. if (!(fromTypeInfo.IsGenericTypeDefinition || fromTypeInfo.IsPointer)) { return(false); } } // If we got here, the types are open, or reduced away, or otherwise lacking in type handles. Perform the IsAssignability check in managed code. return(Assignability.IsAssignableFrom(this, typeInfo, fromTypeInfo.ReflectionDomain.FoundationTypes)); }