Exemplo n.º 1
0
        /// <summary>
        /// Creates a new ReflectedCaller which can be used to quickly invoke the provided MethodInfo.
        /// </summary>
        public static ReflectedCaller Create(MethodInfo info) {
            if ((!info.IsStatic && info.DeclaringType.IsValueType) || 
                info is System.Reflection.Emit.DynamicMethod) {
                return new SlowReflectedCaller(info);
            }            

            ParameterInfo[] pis = info.GetParameters();
            int argCnt = pis.Length;
            if (!info.IsStatic) argCnt++;
            if (argCnt >= MaxHelpers) {
                // no delegate for this size, fallback to reflection invoke
                return new SlowReflectedCaller(info);
            }

            foreach (ParameterInfo pi in pis) {
                if (pi.ParameterType.IsByRef) {
                    // we don't support ref args via generics.
                    return new SlowReflectedCaller(info);
                }
            }

            // see if we've created one w/ a delegate
            ReflectedCaller res;
            if (ShouldCache(info)) {
                lock (_cache) {
                    if (_cache.TryGetValue(info, out res)) {
                        return res;
                    }
                }
            }

            // create it 
            try {
                if (argCnt < MaxArgs) {
                    res = FastCreate(info, pis);
                } else {
                    res = SlowCreate(info, pis);
                }
            } catch (TargetInvocationException tie) {
                if (!(tie.InnerException is NotSupportedException)) {
                    throw;
                }

                res = new SlowReflectedCaller(info);
            } catch (NotSupportedException) {
                // if Delegate.CreateDelegate can't handle the method fallback to 
                // the slow reflection version.  For example this can happen w/ 
                // a generic method defined on an interface and implemented on a class.
                res = new SlowReflectedCaller(info);
            }

            // cache it for future users if it's a reasonable method to cache
            if (ShouldCache(info)) {
                lock (_cache) {
                    _cache[info] = res;
                }
            }

            return res;            
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new ReflectedCaller which can be used to quickly invoke the provided MethodInfo.
        /// </summary>
        public static ReflectedCaller Create(MethodInfo info)
        {
            if ((!info.IsStatic && info.DeclaringType.IsValueType) ||
                info is System.Reflection.Emit.DynamicMethod)
            {
                return(new SlowReflectedCaller(info));
            }

            ParameterInfo[] pis    = info.GetParameters();
            int             argCnt = pis.Length;

            if (!info.IsStatic)
            {
                argCnt++;
            }
            if (argCnt >= MaxHelpers)
            {
                // no delegate for this size, fallback to reflection invoke
                return(new SlowReflectedCaller(info));
            }

            foreach (ParameterInfo pi in pis)
            {
                if (pi.ParameterType.IsByRef)
                {
                    // we don't support ref args via generics.
                    return(new SlowReflectedCaller(info));
                }
            }

            // see if we've created one w/ a delegate
            ReflectedCaller res;

            if (ShouldCache(info))
            {
                lock (_cache) {
                    if (_cache.TryGetValue(info, out res))
                    {
                        return(res);
                    }
                }
            }

            // create it
            try {
                if (argCnt < MaxArgs)
                {
                    res = FastCreate(info, pis);
                }
                else
                {
                    res = SlowCreate(info, pis);
                }
            } catch (TargetInvocationException tie) {
                if (!(tie.InnerException is NotSupportedException))
                {
                    throw;
                }

                res = new SlowReflectedCaller(info);
            } catch (NotSupportedException) {
                // if Delegate.CreateDelegate can't handle the method fallback to
                // the slow reflection version.  For example this can happen w/
                // a generic method defined on an interface and implemented on a class.
                res = new SlowReflectedCaller(info);
            }

            // cache it for future users if it's a reasonable method to cache
            if (ShouldCache(info))
            {
                lock (_cache) {
                    _cache[info] = res;
                }
            }

            return(res);
        }