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

Bind() public method

public Bind ( DynamicMetaObjectBinder payload, IEnumerable parameters, DynamicMetaObject args, DynamicMetaObject &deferredBinding ) : Expression
payload System.Dynamic.DynamicMetaObjectBinder
parameters IEnumerable
args System.Dynamic.DynamicMetaObject
deferredBinding System.Dynamic.DynamicMetaObject
return System.Linq.Expressions.Expression
        public Expression Bind(
            DynamicMetaObjectBinder payload,
            IEnumerable<Expression> parameters,
            DynamicMetaObject[] args,
            out DynamicMetaObject deferredBinding)
        {
            // The lock is here to protect this instance of the binder from itself
            // when called on multiple threads. The cost in time of a single lock
            // on a single thread appears to be negligible and dominated by the cost
            // of the bind itself. My timing of 4000 consecutive dynamic calls with
            // bind, where the body of the called method is empty, are as follows
            // (five samples):
            //
            //   Without lock()         With lock()
            // = 00:00:10.7597696     = 00:00:10.7222606
            // = 00:00:10.0711116     = 00:00:10.1818496
            // = 00:00:09.9905507     = 00:00:10.1628693
            // = 00:00:09.9892183     = 00:00:10.0750007
            // = 00:00:09.9253234     = 00:00:10.0340266
            //
            // ...subsequent calls that were cache hits, i.e., already bound, took less
            // than 1/1000 sec for the whole 4000 of them.

            lock (_bindLock)
            {
                // this is a strategy for realizing correct binding when the symboltable
                // finds a name collision across different types, e.g. one dynamic binding
                // uses a type "N.T" and now a second binding uses a different type "N.T".

                // In order to make this work, we have to reset the symbol table and begin
                // the second binding over again when we detect the collision. So this is
                // something like a longjmp to the beginning of binding. For a single binding,
                // if we have to do this more than once, we give an ICE--this would be a
                // scenario that needs to know about both N.T's simultaneously to work.

                // See SymbolTable.LoadSymbolsFromType for more information.

                try
                {
                    return BindCore(payload, parameters, args, out deferredBinding);
                }
                catch (ResetBindException)
                {
                    Reset();
                    try
                    {
                        return BindCore(payload, parameters, args, out deferredBinding);
                    }
                    catch (ResetBindException)
                    {
                        Reset();
                        Debug.Assert(false, "More than one symbol table name collision in a single binding");
                        throw Error.InternalCompilerError();
                    }
                }
            }
        }