Represents a dynamic property access in C#, providing the binding semantics and the details about the operation. Instances of this class are generated by the C# compiler.
Inheritance: System.Dynamic.GetMemberBinder, IInvokeOnGetBinder
        /// <summary>
        /// DynamicOperatorRewriter in EE generates call to this method to dynamically invoke a property getter
        /// with no arguments.
        /// </summary>
        /// <typeparam name="T">Type of object on which property is defined.</typeparam>
        /// <param name="obj">Object on which property is defined.</param>
        /// <param name="propName">Name of a property to invoke.</param>
        /// <param name="accessibilityContext">Type that determines context in which method should be called.</param>
        /// <param name="isResultIndexed">Determines if COM binder should return a callable object.</param>
        /// <returns>Result of property invocation.</returns>
        public static object TryGetMemberValue <T>(T obj, string propName, Type accessibilityContext, bool isResultIndexed)
        {
            // In most cases it's ok to use CSharpArgumentInfoFlags.None since target of property call is dynamic.
            // The only possible case when target is not dynamic but we still treat is as dynamic access is when
            // one of arguments is dynamic. This is only possible for indexed properties since we call this method and
            // TryGetMemberValueVarArgs afterwards.

            CSharpGetMemberBinder binder = new CSharpGetMemberBinder(
                propName,
                isResultIndexed,
                accessibilityContext,
                new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });

            var site = CallSite <Func <CallSite, T, object> > .Create(binder);

            return(site.Target(site, obj));
        }
Exemple #2
0
        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;
        }