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;
    }
}

参考文档:
.NET Core/Framework 创建委托以大幅度提高反射调用的性能

posted @ 2023-03-13 11:46  wesson2019  阅读(4)  评论(0编辑  收藏  举报