Cacheable representation of an invocation without the target or arguments also by default only does public methods to make it easier to cache. ///
Inheritance: Invocation
Beispiel #1
0
#pragma warning disable 1734
        /// <summary>
        /// Provides the implementation for operations that invoke an object. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as invoking an object or a delegate.
        /// </summary>
        /// <param name="binder">Provides information about the invoke operation.</param>
        /// <param name="args">The arguments that are passed to the object during the invoke operation. For example, for the sampleObject(100) operation, where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="args[0]"/> is equal to 100.</param>
        /// <param name="result">The result of the object invocation.</param>
        /// <returns>
        /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.
        /// </returns>
#pragma warning restore 1734
        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
            var tNamedArgs = Util.NameArgsIfNecessary(binder.CallInfo, args);
            var tNewArgs   = _args.Concat(tNamedArgs).ToArray();

            if (_totalArgCount.HasValue && (_totalArgCount - Args.Length - args.Length > 0))
            //Not Done currying
            {
                result = new PartialApply(Target, tNewArgs, MemberName,
                                          TotalArgCount, InvocationKind);

                return(true);
            }
            var tInvokeDirect = String.IsNullOrWhiteSpace(_memberName);
            var tDel          = _target as Delegate;


            if (tInvokeDirect && binder.CallInfo.ArgumentNames.Count == 0 && _target is Delegate)
            //Optimization for direct delegate calls
            {
                result = tDel.FastDynamicInvoke(tNewArgs);
                return(true);
            }


            Invocation tInvocation;

            if (binder.CallInfo.ArgumentNames.Count == 0) //If no argument names we can cache the callsite
            {
                CacheableInvocation tCacheableInvocation;
                if (!_cacheableInvocation.TryGetValue(tNewArgs.Length, out tCacheableInvocation))
                {
                    tCacheableInvocation = new CacheableInvocation(InvocationKind, _memberName, argCount: tNewArgs.Length, context: _target);
                    _cacheableInvocation[tNewArgs.Length] = tCacheableInvocation;
                }
                tInvocation = tCacheableInvocation;
            }
            else
            {
                tInvocation = new Invocation(InvocationKind, _memberName);
            }

            result = tInvocation.Invoke(_target, tNewArgs);


            return(true);
        }
Beispiel #2
0
 /// <summary>
 /// Equalses the specified other.
 /// </summary>
 /// <param name="other">The other.</param>
 /// <returns></returns>
 public bool Equals(CacheableInvocation other)
 {
     if (ReferenceEquals(null, other))
     {
         return(false);
     }
     if (ReferenceEquals(this, other))
     {
         return(true);
     }
     return(base.Equals(other) &&
            other._argCount == _argCount &&
            Equals(other._argNames, _argNames) &&
            other._staticContext.Equals(_staticContext) &&
            Equals(other._context, _context) &&
            other._convertExplicit.Equals(_convertExplicit) &&
            Equals(other._convertType, _convertType));
 }
 /// <summary>
 /// Equalses the specified other.
 /// </summary>
 /// <param name="other">The other.</param>
 /// <returns></returns>
 public bool Equals(CacheableInvocation other)
 {
     if (ReferenceEquals(null, other)) return false;
     if (ReferenceEquals(this, other)) return true;
     return base.Equals(other)
         && other._argCount == _argCount
         && Equals(other._argNames, _argNames)
         && other._staticContext.Equals(_staticContext)
         && Equals(other._context, _context)
         && other._convertExplicit.Equals(_convertExplicit)
         && Equals(other._convertType, _convertType);
 }
Beispiel #4
0
#pragma warning disable 1734
        /// <summary>
        /// Provides the implementation for operations that invoke an object. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as invoking an object or a delegate.
        /// </summary>
        /// <param name="binder">Provides information about the invoke operation.</param>
        /// <param name="args">The arguments that are passed to the object during the invoke operation. For example, for the sampleObject(100) operation, where sampleObject is derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, <paramref name="args[0]"/> is equal to 100.</param>
        /// <param name="result">The result of the object invocation.</param>
        /// <returns>
        /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.
        /// </returns>
#pragma warning restore 1734
        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
            var tNamedArgs = Util.NameArgsIfNecessary(binder.CallInfo, args);
            var tNewArgs = _args.Concat(tNamedArgs).ToArray();

            if (_totalArgCount.HasValue && (_totalArgCount - Args.Length - args.Length > 0))
            //Not Done currying
            {
                result = new PartialApply(Target, tNewArgs, MemberName,
                                   TotalArgCount, InvocationKind);

                return true;
            }
            var tInvokeDirect = String.IsNullOrWhiteSpace(_memberName);
            var tDel = _target as Delegate;


            if (tInvokeDirect && binder.CallInfo.ArgumentNames.Count == 0 && _target is Delegate)
            //Optimization for direct delegate calls
            {
                result = tDel.FastDynamicInvoke(tNewArgs);
                return true;
            }


            Invocation tInvocation;
            if (binder.CallInfo.ArgumentNames.Count == 0) //If no argument names we can cache the callsite
            {
                CacheableInvocation tCacheableInvocation;
                if (!_cacheableInvocation.TryGetValue(tNewArgs.Length, out tCacheableInvocation))
                {
                    tCacheableInvocation = new CacheableInvocation(InvocationKind, _memberName, argCount: tNewArgs.Length, context: _target);
                    _cacheableInvocation[tNewArgs.Length] = tCacheableInvocation;

                }
                tInvocation = tCacheableInvocation;
            }
            else
            {
                tInvocation = new Invocation(InvocationKind, _memberName);
            }

            result = tInvocation.Invoke(_target, tNewArgs);


            return true;
        }