GetGenericInferenceType() public method

public GetGenericInferenceType ( DynamicMetaObject dynamicObject ) : Type
dynamicObject System.Dynamic.DynamicMetaObject
return System.Type
示例#1
0
        /// <summary>
        /// Provides generic type inference for a single parameter.
        /// </summary>
        /// <remarks>
        /// For example: 
        ///   M{T}(T x)
        ///   M{T}(IList{T} x)
        ///   M{T}(ref T x)
        ///   M{T}(T[] x)
        ///   M{T}(ref Dictionary{T,T}[] x)
        /// </remarks>
        internal static Type GetInferedType(OverloadResolver/*!*/ resolver, Type/*!*/ genericParameter, Type/*!*/ parameterType,
            DynamicMetaObject/*!*/ input, Dictionary<Type, Type>/*!*/ binding, Dictionary<DynamicMetaObject, BindingRestrictions>/*!*/ restrictions) {

            if (parameterType.IsSubclassOf(typeof(Delegate))) {
                // see if we have an invokable object which can be used to infer into this delegate
                IInferableInvokable invokeInfer = input as IInferableInvokable;
                if (invokeInfer != null) {
                    InferenceResult inference = invokeInfer.GetInferredType(parameterType, genericParameter);
                    if (inference != null) {
                        if (inference.Restrictions != BindingRestrictions.Empty) {
                            restrictions[input] = inference.Restrictions;
                        }

                        binding[genericParameter] = inference.Type;

                        if (ConstraintsViolated(inference.Type, genericParameter, binding)) {
                            return null;
                        }

                        return inference.Type;
                    }
                }
            }

            return GetInferedType(genericParameter, parameterType, resolver.GetGenericInferenceType(input), input.LimitType, binding);
        }
示例#2
0
            public override Type GetInferedType(OverloadResolver resolver, Type genericParameter, DynamicMetaObject input, Dictionary<Type, Type> prevConstraints, Dictionary<DynamicMetaObject, BindingRestrictions> restrictions) {
                Type inputType = resolver.GetGenericInferenceType(input);
                if (inputType != null) {
                    prevConstraints[genericParameter] = inputType;
                    if (ConstraintsViolated(inputType, genericParameter, prevConstraints)) {
                        return null;
                    }
                }

                return inputType;
            }
示例#3
0
            public override Type GetInferedType(OverloadResolver resolver, Type genericParameter, DynamicMetaObject input, Dictionary<Type, Type> prevConstraints, Dictionary<DynamicMetaObject, BindingRestrictions> restrictions) {
                Type inputType = resolver.GetGenericInferenceType(input);

                if (ParameterType.IsInterface) {
                    //
                    // The argument can implement multiple instantiations of the same generic interface definition, e.g.
                    // ArgType : I<C<X>>, I<D<Y>>
                    // ParamType == I<C<T>>
                    //
                    // Unless X == Y we can't infer T.
                    //
                    Type[] interfaces = inputType.GetInterfaces();
                    Type match = null;
                    Type genTypeDef = ParameterType.GetGenericTypeDefinition();
                    foreach (Type ifaceType in interfaces) {
                        if (ifaceType.IsGenericType && ifaceType.GetGenericTypeDefinition() == genTypeDef) {
                            if (!MatchGenericParameter(genericParameter, ifaceType, ParameterType, prevConstraints, ref match)) {
                                return null;
                            }
                        }
                    }

                    prevConstraints[genericParameter] = match;
                    return match;
                } else if (ParameterType.IsArray) {
                    return prevConstraints[genericParameter] = MatchGenericParameter(genericParameter, input.LimitType, ParameterType, prevConstraints);
                } else if (ParameterType.IsByRef) {
                    Type argType = input.LimitType;
                    if (CompilerHelpers.IsStrongBox(argType)) {
                        argType = argType.GetGenericArguments()[0];
                    }
                    return prevConstraints[genericParameter] = MatchGenericParameter(genericParameter, argType, ParameterType.GetElementType(), prevConstraints);
                } else if (ParameterType.IsSubclassOf(typeof(Delegate))) {
                    // see if we have an invokable object which can be used to infer into this delegate
                    IInferableInvokable invokeInfer = input as IInferableInvokable;
                    if (invokeInfer != null) {
                        InferenceResult inference = invokeInfer.GetInferredType(ParameterType, genericParameter);
                        if (inference != null) {
                            if (inference.Restrictions != BindingRestrictions.Empty) {
                                restrictions[input] = inference.Restrictions;
                            }

                            prevConstraints[genericParameter] = inference.Type;

                            if (ConstraintsViolated(inference.Type, genericParameter, prevConstraints)) {
                                return null;
                            }

                            return inference.Type;
                        }
                    }
                }

                // see if we're anywhere in our base class hierarchy
                Type curType = input.LimitType;
                Type genType = ParameterType.GetGenericTypeDefinition();
                while (curType != typeof(object)) {
                    if (curType.IsGenericType && curType.GetGenericTypeDefinition() == genType) {
                        // TODO: Merge w/ the interface logic above
                        return prevConstraints[genericParameter] = MatchGenericParameter(genericParameter, curType, ParameterType, prevConstraints);
                    }
                    curType = curType.BaseType;
                }
                

                return null;
            }
示例#4
0
            public override Type GetInferedType(OverloadResolver resolver, Type genericParameter, DynamicMetaObject input, Dictionary<Type, Type> prevConstraints, Dictionary<DynamicMetaObject, BindingRestrictions> restrictions) {
                Type inputType = resolver.GetGenericInferenceType(input);

                if (ParameterType.IsInterface) {
                    // see if we implement this interface exactly once
                    Type[] interfaces = inputType.GetInterfaces();
                    Type targetType = null;
                    Type genTypeDef = ParameterType.GetGenericTypeDefinition();
                    foreach (Type ifaceType in interfaces) {
                        if (ifaceType.IsGenericType && ifaceType.GetGenericTypeDefinition() == genTypeDef) {
                            if (targetType == null) {
                                // we may have a match, figure out the type...
                                targetType = InferGenericType(genericParameter, ifaceType, ParameterType, prevConstraints);
                            } else {
                                // multiple interface implementations match
                                return null;
                            }
                        }
                    }

                    prevConstraints[genericParameter] = targetType;
                    return targetType;
                } else if (ParameterType.IsSubclassOf(typeof(Delegate))) {
                    // see if we have an invokable object which can be used to infer into this delegate
                    IInferableInvokable invokeInfer = input as IInferableInvokable;
                    if (invokeInfer != null) {
                        InferenceResult inference = invokeInfer.GetInferredType(ParameterType, genericParameter);
                        if (inference != null) {
                            if (inference.Restrictions != BindingRestrictions.Empty) {
                                restrictions[input] = inference.Restrictions;
                            }

                            prevConstraints[genericParameter] = inference.Type;

                            if (ConstraintsViolated(inference.Type, genericParameter, prevConstraints)) {
                                return null;
                            }

                            return inference.Type;
                        }
                    }
                }

                // see if we're anywhere in our base class hierarchy
                Type curType = input.LimitType;
                Type genType = ParameterType.GetGenericTypeDefinition();
                while (curType != typeof(object)) {
                    if (curType.IsGenericType) {
                        if (curType.GetGenericTypeDefinition() == genType) {
                            // TODO: Merge w/ the interface logic above
                            Type unboundType = ParameterType;

                            Type res = InferGenericType(genericParameter, curType, unboundType, prevConstraints);
                            prevConstraints[genericParameter] = res;
                            return res;
                        }
                    }
                    curType = curType.BaseType;
                }
                

                return null;
            }