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

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

private GetResults ( ) : TypeArray
Результат TypeArray
        private TypeArray GetResults()
        {
            // Anything we didn't infer a CType for, give the error CType.
            // Note: the error CType will have the same name as the name
            // of the CType parameter we were trying to infer.  This will give a
            // nice user experience where by we will show something like
            // the following:
            //
            // user types: customers.Select(
            // we show   : IE<TResult> IE<Customer>.Select<Customer,TResult>(Func<Customer,TResult> selector)
            //
            // Initially we thought we'd just show ?.  i.e.:
            //
            //  IE<?> IE<Customer>.Select<Customer,?>(Func<Customer,?> selector)
            //
            // This is nice and concise.  However, it falls down if there are multiple
            // CType params that we have left.

            for (int iParam = 0; iParam < _pMethodTypeParameters.size; iParam++)
            {
                // We iterate through the resultant types and replace any that are
                // null, or an error CType that has less information (e.g null name or
                // PredefinedName.PN_MISSING name).

                // We get an ErrorType with a null nameText
                // for a CType variable that we couldn't infer.
                if (_pFixedResults[iParam] != null)
                {
                    if (!_pFixedResults[iParam].IsErrorType())
                    {
                        continue;
                    }

                    Name pErrorTypeName = _pFixedResults[iParam].AsErrorType().nameText;
                    if (pErrorTypeName != null &&
                        pErrorTypeName != GetGlobalSymbols().GetNameManager().GetPredefName(PredefinedName.PN_MISSING))
                    {
                        continue;
                    }
                }

                _pFixedResults[iParam] = GetTypeManager().GetErrorType(
                                        null/*pParentType*/,
                                        null,
                                        _pMethodTypeParameters.ItemAsTypeParameterType(iParam).GetName(),
                                        BSYMMGR.EmptyTypeArray());
            }
            return GetGlobalSymbols().AllocParams(_pMethodTypeParameters.size, _pFixedResults);
        }

Usage Example

Пример #1
0
        /*
        SPEC:

        CType inference occurs as part of the compile-time processing of a method invocation
        and takes place before the overload resolution step of the invocation. When a
        particular method group is specified in a method invocation, and no CType arguments
        are specified as part of the method invocation, CType inference is applied to each
        generic method in the method group. If CType inference succeeds, then the inferred
        CType arguments are used to determine the types of formal parameters for subsequent 
        overload resolution. If overload resolution chooses a generic method as the one to
        invoke then the inferred CType arguments are used as the actual CType arguments for the
        invocation. If CType inference for a particular method fails, that method does not
        participate in overload resolution. The failure of CType inference, in and of itself,
        does not cause a compile-time error. However, it often leads to a compile-time error
        when overload resolution then fails to find any applicable methods.

        If the supplied number of arguments is different than the number of parameters in
        the method, then inference immediately fails. Otherwise, assume that the generic
        method has the following signature:

        Tr M<X1...Xn>(T1 x1 ... Tm xm)

        With a method call of the form M(E1...Em) the task of CType inference is to find
        unique CType arguments S1...Sn for each of the CType parameters X1...Xn so that the
        call M<S1...Sn>(E1...Em)becomes valid.

        During the process of inference each CType parameter Xi is either fixed to a particular
        CType Si or unfixed with an associated set of bounds. Each of the bounds is some CType T.
        Each bound is classified as an upper bound, lower bound or exact bound.
        Initially each CType variable Xi is unfixed with an empty set of bounds.


        */

        // This file contains the implementation for method CType inference on calls (with
        // arguments, and method CType inference on conversion of method groups to delegate
        // types (which will not have arguments.)

        ////////////////////////////////////////////////////////////////////////////////

        public static bool Infer(
            ExpressionBinder binder,
            SymbolLoader symbolLoader,
            MethodSymbol pMethod,
            TypeArray pClassTypeArguments,
            TypeArray pMethodFormalParameterTypes,
            ArgInfos pMethodArguments,
            out TypeArray ppInferredTypeArguments)
        {
            Debug.Assert(pMethod != null);
            Debug.Assert(pMethod.typeVars.size > 0);
            Debug.Assert(pMethod.isParamArray || pMethod.Params == pMethodFormalParameterTypes);
            ppInferredTypeArguments = null;
            if (pMethodFormalParameterTypes.size == 0 || pMethod.InferenceMustFail())
            {
                return false;
            }
            Debug.Assert(pMethodArguments != null);
            Debug.Assert(pMethodFormalParameterTypes != null);
            Debug.Assert(pMethodArguments.carg <= pMethodFormalParameterTypes.size);

            var inferrer = new MethodTypeInferrer(binder, symbolLoader,
                pMethodFormalParameterTypes, pMethodArguments,
                pMethod.typeVars, pClassTypeArguments);
            bool success;
            if (pMethodArguments.fHasExprs)
            {
                success = inferrer.InferTypeArgs();
            }
            else
            {
                success = inferrer.InferForMethodGroupConversion();
            }

            ppInferredTypeArguments = inferrer.GetResults();
            return success;
        }