Microsoft.CSharp.RuntimeBinder.RuntimeBinder.DeferBinding C# (CSharp) Method

DeferBinding() private method

private DeferBinding ( DynamicMetaObjectBinder payload, ArgumentObject arguments, DynamicMetaObject args, LocalVariableSymbol>.Dictionary dictionary, DynamicMetaObject &deferredBinding ) : bool
payload System.Dynamic.DynamicMetaObjectBinder
arguments ArgumentObject
args System.Dynamic.DynamicMetaObject
dictionary LocalVariableSymbol>.Dictionary
deferredBinding System.Dynamic.DynamicMetaObject
return bool
        private bool DeferBinding(
            DynamicMetaObjectBinder payload,
            ArgumentObject[] arguments,
            DynamicMetaObject[] args,
            Dictionary<int, LocalVariableSymbol> dictionary,
            out DynamicMetaObject deferredBinding)
        {
            // This method deals with any deferrals we need to do. We check deferrals up front
            // and bail early if we need to do them.

            // (1) InvokeMember deferral.
            //
            // This is the deferral for the d.Foo() scenario where Foo actually binds to a 
            // field or property, and not a method group that is invocable. We defer to
            // the standard GetMember/Invoke pattern.

            if (payload is CSharpInvokeMemberBinder)
            {
                ICSharpInvokeOrInvokeMemberBinder callPayload = payload as ICSharpInvokeOrInvokeMemberBinder;
                int arity = callPayload.TypeArguments != null ? callPayload.TypeArguments.Count : 0;
                MemberLookup mem = new MemberLookup();
                EXPR callingObject = CreateCallingObjectForCall(callPayload, arguments, dictionary);

                Debug.Assert(_bindingContext.ContextForMemberLookup() != null);
                SymWithType swt = _symbolTable.LookupMember(
                        callPayload.Name,
                        callingObject,
                        _bindingContext.ContextForMemberLookup(),
                        arity,
                        mem,
                        (callPayload.Flags & CSharpCallFlags.EventHookup) != 0,
                        true);

                if (swt != null && swt.Sym.getKind() != SYMKIND.SK_MethodSymbol)
                {
                    // The GetMember only has one argument, and we need to just take the first arg info.
                    CSharpGetMemberBinder getMember = new CSharpGetMemberBinder(callPayload.Name, false, callPayload.CallingContext, new CSharpArgumentInfo[] { callPayload.ArgumentInfo[0] });

                    // The Invoke has the remaining argument infos. However, we need to redo the first one
                    // to correspond to the GetMember result.
                    CSharpArgumentInfo[] argInfos = new CSharpArgumentInfo[callPayload.ArgumentInfo.Count];
                    callPayload.ArgumentInfo.CopyTo(argInfos, 0);

                    argInfos[0] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
                    CSharpInvokeBinder invoke = new CSharpInvokeBinder(callPayload.Flags, callPayload.CallingContext, argInfos);

                    DynamicMetaObject[] newArgs = new DynamicMetaObject[args.Length - 1];
                    Array.Copy(args, 1, newArgs, 0, args.Length - 1);
                    deferredBinding = invoke.Defer(getMember.Defer(args[0]), newArgs);
                    return true;
                }
            }

            deferredBinding = null;
            return false;
        }