protected virtual Delegate TryCreateDelegateInternal(Type delegateType, object target, MethodInfo method)
        {
            MethodInfo result;

            lock (CachedDelegates)
            {
                var cacheKey = new MethodDelegateCacheKey(method, delegateType);
                if (!CachedDelegates.TryGetValue(cacheKey, out result))
                {
                    result = TryCreateMethodDelegate(delegateType, method);
                    CachedDelegates[cacheKey] = result;
                    if (result != null)
                    {
                        GenerateDelegateFactoryCode(delegateType, result);
                    }
                }
                if (result == null)
                {
                    return(null);
                }
            }
#if NET_STANDARD
            if (target == null)
            {
                return(result.CreateDelegate(delegateType));
            }
            return(result.CreateDelegate(delegateType, target));
#else
            if (target == null)
            {
                return(Delegate.CreateDelegate(delegateType, result));
            }
            return(Delegate.CreateDelegate(delegateType, target, result));
#endif
        }
示例#2
0
        /// <summary>
        ///    Tries to creates a delegate of the specified type that represents the specified static or instance method, with the specified first argument.
        /// </summary>
        /// <returns>
        ///     A delegate of the specified type that represents the specified static method of the specified class.
        /// </returns>
        /// <param name="delegateType">The <see cref="T:System.Type" /> of delegate to create. </param>
        /// <param name="target">
        ///     The <see cref="T:System.Type" /> representing the class that implements <paramref name="method" />
        ///     .
        /// </param>
        /// <param name="method">The name of the static method that the delegate is to represent. </param>
        public virtual Delegate TryCreateDelegate(Type delegateType, object target, MethodInfo method)
        {
            MethodInfo result;

            lock (CachedDelegates)
            {
                var cacheKey = new MethodDelegateCacheKey(method, delegateType);
                if (!CachedDelegates.TryGetValue(cacheKey, out result))
                {
                    result = TryCreateMethodDelegate(delegateType, method);
                    CachedDelegates[cacheKey] = result;
                }
                if (result == null)
                {
                    return(null);
                }
            }
#if PCL_WINRT
            if (target == null)
            {
                return(result.CreateDelegate(delegateType));
            }
            return(result.CreateDelegate(delegateType, target));
#else
            if (target == null)
            {
                return(Delegate.CreateDelegate(delegateType, result));
            }
            return(Delegate.CreateDelegate(delegateType, target, result));
#endif
        }
        protected virtual Delegate GetMethodDelegateInternal(Type delegateType, MethodInfo method)
        {
            lock (InvokeMethodCacheDelegate)
            {
                var      cacheKey = new MethodDelegateCacheKey(method, delegateType);
                Delegate value;
                if (!InvokeMethodCacheDelegate.TryGetValue(cacheKey, out value))
                {
                    GenerateInvokeMethodCode(method, delegateType);
                    MethodInfo delegateMethod = delegateType.GetMethodEx(nameof(Action.Invoke));
                    if (delegateMethod == null)
                    {
                        throw new ArgumentException(string.Empty, nameof(delegateType));
                    }

                    var             delegateParams = delegateMethod.GetParameters().ToList();
                    ParameterInfo[] methodParams   = method.GetParameters();
                    var             expressions    = new List <Expression>();
                    var             parameters     = new List <ParameterExpression>();
                    if (!method.IsStatic)
                    {
                        var thisParam = Expression.Parameter(delegateParams[0].ParameterType, "@this");
                        parameters.Add(thisParam);
                        expressions.Add(ConvertIfNeed(thisParam, method.DeclaringType, false));
                        delegateParams.RemoveAt(0);
                    }
                    Should.BeValid("delegateType", delegateParams.Count == methodParams.Length);
                    for (int i = 0; i < methodParams.Length; i++)
                    {
                        ParameterExpression parameter = Expression.Parameter(delegateParams[i].ParameterType, i.ToString());
                        parameters.Add(parameter);
                        expressions.Add(ConvertIfNeed(parameter, methodParams[i].ParameterType, false));
                    }

                    Expression callExpression;
                    if (method.IsStatic)
                    {
                        callExpression = Expression.Call(null, method, expressions.ToArrayEx());
                    }
                    else
                    {
                        Expression @this = expressions[0];
                        expressions.RemoveAt(0);
                        callExpression = Expression.Call(@this, method, expressions.ToArrayEx());
                    }

                    if (delegateMethod.ReturnType != typeof(void))
                    {
                        callExpression = ConvertIfNeed(callExpression, delegateMethod.ReturnType, false);
                    }
                    var lambdaExpression = Expression.Lambda(delegateType, callExpression, parameters);
                    value = lambdaExpression.Compile();
                    InvokeMethodCacheDelegate[cacheKey] = value;
                }
                return(value);
            }
        }
示例#4
0
        /// <summary>
        ///     Gets a delegate to call the specified <see cref="MethodInfo" />.
        /// </summary>
        /// <param name="delegateType">The type of delegate.</param>
        /// <param name="method">
        ///     The specified <see cref="MethodInfo" />
        /// </param>
        /// <returns>
        ///     An instance of delegate.
        /// </returns>
        public virtual Delegate GetMethodDelegate(Type delegateType, MethodInfo method)
        {
            Should.NotBeNull(delegateType, "delegateType");
            Should.BeOfType <Delegate>(delegateType, "delegateType");
            Should.NotBeNull(method, "method");
            lock (InvokeMethodCacheDelegate)
            {
                var      cacheKey = new MethodDelegateCacheKey(method, delegateType);
                Delegate value;
                if (!InvokeMethodCacheDelegate.TryGetValue(cacheKey, out value))
                {
                    MethodInfo      delegateMethod = delegateType.GetMethodEx("Invoke");
                    var             delegateParams = delegateMethod.GetParameters().ToList();
                    ParameterInfo[] methodParams   = method.GetParameters();
                    var             expressions    = new List <Expression>();
                    var             parameters     = new List <ParameterExpression>();
                    if (!method.IsStatic)
                    {
                        var thisParam = Expression.Parameter(delegateParams[0].ParameterType, "@this");
                        parameters.Add(thisParam);
                        expressions.Add(ConvertIfNeed(thisParam, GetDeclaringType(method), false));
                        delegateParams.RemoveAt(0);
                    }
                    Should.BeValid("delegateType", delegateParams.Count == methodParams.Length);
                    for (int i = 0; i < methodParams.Length; i++)
                    {
                        ParameterExpression parameter = Expression.Parameter(delegateParams[i].ParameterType, i.ToString());
                        parameters.Add(parameter);
                        expressions.Add(ConvertIfNeed(parameter, methodParams[i].ParameterType, false));
                    }

                    Expression callExpression;
                    if (method.IsStatic)
                    {
                        callExpression = Expression.Call(null, method, expressions.ToArrayEx());
                    }
                    else
                    {
                        Expression @this = expressions[0];
                        expressions.RemoveAt(0);
                        callExpression = Expression.Call(@this, method, expressions.ToArrayEx());
                    }

                    if (delegateMethod.ReturnType != typeof(void))
                    {
                        callExpression = ConvertIfNeed(callExpression, delegateMethod.ReturnType, false);
                    }
                    var lambdaExpression = CreateLambdaExpressionByType(delegateType, callExpression, parameters);
                    value = lambdaExpression.Compile();
                    InvokeMethodCacheDelegate[cacheKey] = value;
                }
                return(value);
            }
        }
        public override Delegate TryCreateDelegate(Type delegateType, object target, MethodInfo method)
        {
            Func <object, Delegate> value;

            lock (DelegatesCache)
            {
                var key = new MethodDelegateCacheKey(method, delegateType);
                if (!DelegatesCache.TryGetValue(key, out value))
                {
                    method = TryCreateMethodDelegate(delegateType, method);
                    if (method != null)
                    {
                        Type          type          = method.DeclaringType;
                        DynamicMethod dynamicMethod = CreateDynamicMethod(type, new[] { typeof(object) },
                                                                          typeof(Delegate));
                        ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
                        if (method.IsStatic)
                        {
                            ilGenerator.Emit(OpCodes.Ldnull);
                        }
                        else
                        {
                            ilGenerator.Emit(OpCodes.Ldarg_0);
                            UnboxOrCast(ilGenerator, type);
                        }
                        if (method.IsVirtual)
                        {
                            ilGenerator.Emit(OpCodes.Dup);
                            ilGenerator.Emit(OpCodes.Ldvirtftn, method);
                        }
                        else
                        {
                            ilGenerator.Emit(OpCodes.Ldftn, method);
                        }
                        ilGenerator.Emit(OpCodes.Newobj, delegateType.GetConstructors()[0]);
                        ilGenerator.Emit(OpCodes.Ret);
                        value = (Func <object, Delegate>)dynamicMethod.CreateDelegate(typeof(Func <object, Delegate>));
                    }
                    DelegatesCache[key] = value;
                }
            }
            if (value == null)
            {
                return(null);
            }
            return(value(target));
        }
 protected override Delegate TryCreateDelegateInternal(Type delegateType, object target, MethodInfo method)
 {
     Func<object, Delegate> value;
     lock (DelegatesCache)
     {
         var key = new MethodDelegateCacheKey(method, delegateType);
         if (!DelegatesCache.TryGetValue(key, out value))
         {
             method = TryCreateMethodDelegate(delegateType, method);
             if (method != null)
             {
                 GenerateDelegateFactoryCode(delegateType, method);
                 Type type = method.DeclaringType;
                 DynamicMethod dynamicMethod = CreateDynamicMethod(type, new[] { typeof(object) },
                     typeof(Delegate));
                 ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
                 if (method.IsStatic)
                     ilGenerator.Emit(OpCodes.Ldnull);
                 else
                 {
                     ilGenerator.Emit(OpCodes.Ldarg_0);
                     UnboxOrCast(ilGenerator, type);
                 }
                 if (method.IsVirtual)
                 {
                     ilGenerator.Emit(OpCodes.Dup);
                     ilGenerator.Emit(OpCodes.Ldvirtftn, method);
                 }
                 else
                     ilGenerator.Emit(OpCodes.Ldftn, method);
                 ilGenerator.Emit(OpCodes.Newobj, delegateType.GetConstructors()[0]);
                 ilGenerator.Emit(OpCodes.Ret);
                 value = (Func<object, Delegate>)dynamicMethod.CreateDelegate(typeof(Func<object, Delegate>));
             }
             DelegatesCache[key] = value;
         }
     }
     if (value == null)
         return null;
     return value(target);
 }