private static bool CanCastToClass(this TypeDesc thisType, TypeDesc otherType, StackOverflowProtect protect) { TypeDesc curType = thisType; if (curType.IsInterface && otherType.IsObject) { return(true); } // If the target type has variant type parameters, we take a slower path if (curType.HasVariance) { // First chase inheritance hierarchy until we hit a class that only differs in its instantiation do { if (curType == otherType) { return(true); } if (curType.CanCastByVarianceToInterfaceOrDelegate(otherType, protect)) { return(true); } curType = curType.BaseType; }while (curType != null); } else { // If there are no variant type parameters, just chase the hierarchy // Allow curType to be nullable, which means this method // will additionally return true if curType is Nullable<T> && ( // currType == otherType // OR otherType is System.ValueType or System.Object) // Always strip Nullable from the otherType, if present if (otherType.IsNullable && !curType.IsNullable) { return(thisType.CanCastTo(otherType.Instantiation[0])); } do { if (curType == otherType) { return(true); } curType = curType.BaseType; } while (curType != null); } return(false); }
private static bool CanCastToInterface(this TypeDesc thisType, TypeDesc otherType, StackOverflowProtect protect) { if (!otherType.HasVariance) { return(thisType.CanCastToNonVariantInterface(otherType, protect)); } else { if (thisType.CanCastByVarianceToInterfaceOrDelegate(otherType, protect)) { return(true); } foreach (var interfaceType in thisType.RuntimeInterfaces) { if (interfaceType.CanCastByVarianceToInterfaceOrDelegate(otherType, protect)) { return(true); } } } return(false); }