Пример #1
0
        private static bool CanCastByVarianceToInterfaceOrDelegate(this TypeDesc thisType, TypeDesc otherType, StackOverflowProtect protectInput)
        {
            if (!thisType.HasSameTypeDefinition(otherType))
            {
                return(false);
            }

            var stackOverflowProtectKey = new CastingPair(thisType, otherType);

            if (protectInput != null)
            {
                if (protectInput.Contains(stackOverflowProtectKey))
                {
                    return(false);
                }
            }

            StackOverflowProtect protect = new StackOverflowProtect(stackOverflowProtectKey, protectInput);

            Instantiation instantiationThis   = thisType.Instantiation;
            Instantiation instantiationTarget = otherType.Instantiation;
            Instantiation instantiationOpen   = thisType.GetTypeDefinition().Instantiation;

            Debug.Assert(instantiationThis.Length == instantiationTarget.Length &&
                         instantiationThis.Length == instantiationOpen.Length);

            for (int i = 0; i < instantiationThis.Length; i++)
            {
                TypeDesc arg       = instantiationThis[i];
                TypeDesc targetArg = instantiationTarget[i];

                if (arg != targetArg)
                {
                    GenericParameterDesc openArgType = (GenericParameterDesc)instantiationOpen[i];

                    switch (openArgType.Variance)
                    {
                    case GenericVariance.Covariant:
                        if (!arg.IsBoxedAndCanCastTo(targetArg, protect))
                        {
                            return(false);
                        }
                        break;

                    case GenericVariance.Contravariant:
                        if (!targetArg.IsBoxedAndCanCastTo(arg, protect))
                        {
                            return(false);
                        }
                        break;

                    default:
                        // non-variant
                        Debug.Assert(openArgType.Variance == GenericVariance.None);
                        return(false);
                    }
                }
            }

            return(true);
        }