Microsoft.CSharp.RuntimeBinder.Semantics.MethodTypeInferrer.CanInferExtensionObject C# (CSharp) Метод

CanInferExtensionObject() приватный Метод

private CanInferExtensionObject ( ) : bool
Результат bool
        private bool CanInferExtensionObject()
        {
            Debug.Assert(_pMethodFormalParameterTypes != null);
            Debug.Assert(_pMethodFormalParameterTypes.size >= 1);
            Debug.Assert(_pMethodArguments != null);
            Debug.Assert(_pMethodArguments.carg >= 1);
            CType pDest = _pMethodFormalParameterTypes.Item(0);
            CType pSource = _pMethodArguments.types.Item(0);
            if (pDest.IsParameterModifierType())
            {
                pDest = pDest.AsParameterModifierType().GetParameterType();
            }
            if (pSource.IsParameterModifierType())
            {
                // This seems impossible, but this is an error scenario, so
                // who knows?  We'll err on the side of caution.
                pSource = pSource.AsParameterModifierType().GetParameterType();
            }
            // Rule out lambdas, nulls, and so on.
            if (!IsReallyAType(pSource))
            {
                return false;
            }
            LowerBoundInference(pSource, pDest);
            // Now check to see that every CType parameter used by the first
            // formal parameter CType was successfully inferred.
            for (int iParam = 0; iParam < _pMethodTypeParameters.size; ++iParam)
            {
                TypeParameterType pParam = _pMethodTypeParameters.ItemAsTypeParameterType(iParam);
                if (!TypeManager.TypeContainsType(pDest, pParam))
                {
                    continue;
                }
                Debug.Assert(IsUnfixed(iParam));
                if (!HasBound(iParam) || !Fix(iParam))
                {
                    return false;
                }
            }
            return true;
        }
    }

Usage Example

Пример #1
0
        ////////////////////////////////////////////////////////////////////////////////
        //
        // In error recovery and reporting scenarios we sometimes end up in a situation
        // like this:
        //
        // x.Foo( y=>
        //
        // and the question is, "is Foo a valid extension method of x?"  If Foo is
        // generic, then Foo will be something like:
        //
        // static Blah Foo<T>(this Bar<T> bar, Func<T, T> f){ ... }
        //
        // What we would like to know is: given _only_ the expression x, can we infer
        // what T is in Bar<T> ?  If we can, then for error recovery and reporting
        // we can provisionally consider Foo to be an extension method of x. If we 
        // cannot deduce this just from x then we should consider Foo to not be an
        // extension method of x, at least until we have more information.
        //
        // Clearly it is pointless to run multiple phases

        public static bool CanObjectOfExtensionBeInferred(
            ExpressionBinder binder,
            SymbolLoader symbolLoader,
            MethodSymbol pMethod,
            TypeArray pClassTypeArguments,
            TypeArray pMethodFormalParameterTypes,
            ArgInfos pMethodArguments)
        {
            Debug.Assert(pMethod != null);
            Debug.Assert(pMethod.typeVars.size > 0);
            Debug.Assert(pMethodFormalParameterTypes != null);
            Debug.Assert(pMethod.isParamArray || pMethod.Params == pMethodFormalParameterTypes);
            // We need at least one formal parameter type and at least one argument.
            if (pMethodFormalParameterTypes.size < 1 || pMethod.InferenceMustFail())
            {
                return false;
            }
            Debug.Assert(pMethodArguments != null);
            Debug.Assert(pMethodArguments.carg <= pMethodFormalParameterTypes.size);
            if (pMethodArguments.carg < 1)
            {
                return false;
            }
            var inferrer = new MethodTypeInferrer(binder, symbolLoader,
            pMethodFormalParameterTypes, pMethodArguments, pMethod.typeVars, pClassTypeArguments);
            return inferrer.CanInferExtensionObject();
        }