GenerateDelegateHelper 委托相关
委托转换
public class GenerateDelegateHelper
{
/// <summary>
/// 委托转换
/// </summary>
/// <typeparam name="T">目标委托类型</typeparam>
/// <param name="delegate">当前委托对象</param>
/// <returns></returns>
public static T GenerateDelegate<T>(Delegate @delegate) where T : class
{
var rslt = Delegate.CreateDelegate(typeof(T), @delegate.Target, @delegate.Method);
return rslt as T;
}
}
// delegate1 转 delegate2
var delegate2 = GenerateDelegateHelper.GenerateDelegate(delegate1);
方法转为委托
方法转 Func
using System;
using System.Reflection;
/// <summary>
/// 生成Func委托
/// </summary>
/// <typeparam name="TReturnValue">返回类型</typeparam>
public static class GenerateDelegateFuncHelper<TReturnValue>
{
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="instance">方法所属实例</param>
/// <param name="methodName">方法信息</param>
/// <returns></returns>
public static Func<TReturnValue> CreateDelegate<TInstanceType>(TInstanceType instance, string methodName)
{
if (instance == null)
{
throw new ArgumentNullException(nameof(instance));
}
if (string.IsNullOrWhiteSpace(methodName))
{
throw new ArgumentNullException(nameof(methodName));
}
var method = typeof(TInstanceType).GetMethod(methodName, new Type[0]);
return (Func<TReturnValue>)method.CreateDelegate(typeof(Func<TReturnValue>), instance);
}
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="method">方法信息</param>
/// <returns></returns>
public static Func<TInstanceType, TReturnValue> CreateDelegate<TInstanceType>(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
return (Func<TInstanceType, TReturnValue>)method.CreateDelegate(typeof(Func<TInstanceType, TReturnValue>));
}
}
/// <summary>
/// 生成Func委托
/// </summary>
/// <typeparam name="T">参数类型</typeparam>
/// <typeparam name="TReturnValue">返回类型</typeparam>
public static class GenerateDelegateFuncHelper<T, TReturnValue>
{
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="instance">方法所属实例</param>
/// <param name="methodName">方法名称</param>
/// <returns></returns>
public static Func<T, TReturnValue> CreateDelegate<TInstanceType>(TInstanceType instance, string methodName)
{
if (instance == null)
{
throw new ArgumentNullException(nameof(instance));
}
if (string.IsNullOrWhiteSpace(methodName))
{
throw new ArgumentNullException(nameof(methodName));
}
var types = new Type[] { typeof(T) };
var method = typeof(TInstanceType).GetMethod(methodName, types);
return (Func<T, TReturnValue>)method.CreateDelegate(typeof(Func<T, TReturnValue>), instance);
}
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="method">方法信息</param>
/// <returns></returns>
public static Func<TInstanceType, T, TReturnValue> CreateDelegate<TInstanceType>(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
return (Func<TInstanceType, T, TReturnValue>)method.CreateDelegate(typeof(Func<TInstanceType, T, TReturnValue>));
}
}
/// <summary>
/// 生成Func委托
/// </summary>
/// <typeparam name="T1">参数1类型</typeparam>
/// <typeparam name="T2">参数2类型</typeparam>
/// <typeparam name="TReturnValue">返回类型</typeparam>
public static class GenerateDelegateFuncHelper<T1, T2, TReturnValue>
{
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="instance">方法所属实例</param>
/// <param name="methodName">方法名称</param>
/// <returns></returns>
public static Func<T1, T2, TReturnValue> CreateDelegate<TInstanceType>(TInstanceType instance, string methodName)
{
if (instance == null)
{
throw new ArgumentNullException(nameof(instance));
}
if (string.IsNullOrWhiteSpace(methodName))
{
throw new ArgumentNullException(nameof(methodName));
}
var types = new Type[] { typeof(T1), typeof(T2) };
var method = typeof(TInstanceType).GetMethod(methodName, types);
return (Func<T1, T2, TReturnValue>)method.CreateDelegate(typeof(Func<T1, T2, TReturnValue>), instance);
}
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="method">方法信息</param>
/// <returns></returns>
public static Func<TInstanceType, T1, T2, TReturnValue> CreateDelegate<TInstanceType>(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
return (Func<TInstanceType, T1, T2, TReturnValue>)method.CreateDelegate(typeof(Func<TInstanceType, T1, T2, TReturnValue>));
}
}
// 其他泛型类似。。。。。。
// public string NormalMethod(int a, int b) {}
var func = GenerateDelegateFuncHelper<int, int, string>.CreateDelegate(obj, "NormalMethod");
var rslt = func(1, 2);
方法转 Action
using System;
using System.Reflection;
/// <summary>
/// 生成Action委托
/// </summary>
public class GenerateDelegateActHelper
{
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="instance">方法所属实例</param>
/// <param name="methodName">方法名称</param>
/// <returns></returns>
public static Action CreateDelegate<TInstanceType>(TInstanceType instance, string methodName)
{
if (instance == null)
{
throw new ArgumentNullException(nameof(instance));
}
if (string.IsNullOrWhiteSpace(methodName))
{
throw new ArgumentNullException(nameof(methodName));
}
var method = typeof(TInstanceType).GetMethod(methodName, new Type[0]);
return (Action)method.CreateDelegate(typeof(Action), instance);
}
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="method">方法信息</param>
/// <returns></returns>
public static Action<TInstanceType> CreateDelegate<TInstanceType>(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
return (Action<TInstanceType>)method.CreateDelegate(typeof(Func<TInstanceType>));
}
}
/// <summary>
/// 生成Action委托
/// </summary>
/// <typeparam name="T"></typeparam>
public class GenerateDelegateActHelper<T>
{
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="instance">方法所属实例</param>
/// <param name="methodName">方法名称</param>
/// <returns></returns>
public static Action<T> CreateDelegate<TInstanceType>(TInstanceType instance, string methodName)
{
if (instance == null)
{
throw new ArgumentNullException(nameof(instance));
}
if (string.IsNullOrWhiteSpace(methodName))
{
throw new ArgumentNullException(nameof(methodName));
}
var types = new Type[] { typeof(T) };
var method = typeof(TInstanceType).GetMethod(methodName, types);
return (Action<T>)method.CreateDelegate(typeof(Action<T>), instance);
}
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="method">方法信息</param>
/// <returns></returns>
public static Action<TInstanceType, T> CreateDelegate<TInstanceType>(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
return (Action<TInstanceType, T>)method.CreateDelegate(typeof(Func<TInstanceType, T>));
}
}
/// <summary>
/// 生成Action委托
/// </summary>
/// <typeparam name="T1">参数1类型</typeparam>
/// <typeparam name="T2">参数2类型</typeparam>
public class GenerateDelegateActHelper<T1, T2>
{
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="instance">方法所属实例</param>
/// <param name="methodName">方法名称</param>
/// <returns></returns>
public static Action<T1, T2> CreateDelegate<TInstanceType>(TInstanceType instance, string methodName)
{
if (instance == null)
{
throw new ArgumentNullException(nameof(instance));
}
if (string.IsNullOrWhiteSpace(methodName))
{
throw new ArgumentNullException(nameof(methodName));
}
var types = new Type[] { typeof(T1), typeof(T2) };
var method = typeof(TInstanceType).GetMethod(methodName, types);
return (Action<T1, T2>)method.CreateDelegate(typeof(Action<T1, T2>), instance);
}
/// <summary>
/// 创建方法的委托
/// </summary>
/// <typeparam name="TInstanceType">方法所属实例的类型</typeparam>
/// <param name="method">方法信息</param>
/// <returns></returns>
public static Action<TInstanceType, T1, T2> CreateDelegate<TInstanceType>(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
return (Action<TInstanceType, T1, T2>)method.CreateDelegate(typeof(Func<TInstanceType, T1, T2>));
}
}
// 其他泛型类似。。。。。。
// public void NormalMethod(int a, int b) {}
var act = GenerateDelegateFuncHelper<int, int>.CreateDelegate(obj, "NormalMethod");
act(1, 2);
委托类型
如果不使用泛型,可以考虑 DynamicInvoke 方式。
public static object InvokeMethod(object obj, string methodName, object[] argsValue)
{
Type type = obj.GetType();
if (obj == null) throw new ArgumentNullException(nameof(obj));
Type[] argsType = new Type[0];
if (argsValue != null)
{
argsType = argsValue.Select(s => s.GetType()).ToArray();
}
// 使用反射找到的方法
var method = type.GetMethod(methodName, argsType);
if (method == null) throw new ArgumentNullException(nameof(method));
try
{
// 将反射找到的方法创建一个委托
var delegate1 = Delegate.CreateDelegate(new DelegateTypeFactory().CreateDelegateType(method), obj, method);
return delegate1.DynamicInvoke(argsValue);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
var binderAttr = BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
return type.InvokeMember(methodName, binderAttr, Type.DefaultBinder, obj, argsValue, null, null, null);
}
因为使用了 DynamicInvoke,执行最耗时(比明确泛型的委托转换 慢了一个数量级)。具体应用场景待定!!!
DelegateTypeFactory
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
public class DelegateTypeFactory
{
private readonly ModuleBuilder _module;
public DelegateTypeFactory()
{
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(nameof(DelegateTypeFactory)), AssemblyBuilderAccess.RunAndCollect);
_module = assembly.DefineDynamicModule(nameof(DelegateTypeFactory));
}
public Type CreateDelegateType(MethodInfo methodInfo)
{
string nameBase = string.Format("{0}{1}", methodInfo.DeclaringType.Name, methodInfo.Name);
string name = GetUniqueName(nameBase);
var typeBuilder = _module.DefineType(name, TypeAttributes.Sealed | TypeAttributes.Public, typeof(MulticastDelegate));
var constructor = typeBuilder.DefineConstructor(MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.Standard,
new[] { typeof(object), typeof(IntPtr) });
constructor.SetImplementationFlags(MethodImplAttributes.CodeTypeMask);
var parameters = methodInfo.GetParameters();
var invokeMethod = typeBuilder.DefineMethod("Invoke", MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public,
methodInfo.ReturnType, parameters.Select(s => s.ParameterType).ToArray());
invokeMethod.SetImplementationFlags(MethodImplAttributes.CodeTypeMask);
for (int i = 0; i < parameters.Length; i++)
{
var para = parameters[i];
invokeMethod.DefineParameter(i + 1, ParameterAttributes.None, para.Name);
}
return typeBuilder.CreateType();
}
private string GetUniqueName(string nameBase)
{
int number = 2;
string name = nameBase;
while (_module.GetType(name) != null)
{
name = nameBase + number++;
}
return name;
}
}