using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace Serein.Library.Utils
{
///
/// Emit创建委托工具类
///
public class EmitHelper
{
///
/// 动态方法信息
///
public class EmitMethodInfo
{
///
/// 方法声明类型
///
public Type DeclaringType { get; set; }
///
/// 方法类型
///
public EmitMethodType EmitMethodType { get; set; }
///
/// 是异步方法
///
public bool IsAsync { get; set; }
///
/// 是静态的
///
public bool IsStatic { get; set; }
}
///
/// 方法类型枚举
///
public enum EmitMethodType
{
///
/// 普通的方法。如果方法返回void时,将会返回null。
///
Func,
///
/// 无返回值的异步方法
///
Task,
///
/// 有返回值的异步方法
///
TaskHasResult,
}
///
/// 判断一个类型是否为泛型 Task<T> 或 Task,并返回泛型参数类型(如果有的话)
///
///
///
///
#nullable enable
public static bool IsGenericTask(Type returnType, out Type? taskResult)
{
// 判断是否为 Task 类型或泛型 Task
if (returnType == typeof(Task))
{
taskResult = typeof(void);
return true;
}
else if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
{
// 获取泛型参数类型
Type genericArgument = returnType.GetGenericArguments()[0];
taskResult = genericArgument;
return true;
}
else
{
taskResult = null;
return false;
}
}
///
/// 根据方法信息创建动态调用的委托,返回方法类型,以及传出一个委托
///
///
///
///
public static EmitMethodInfo CreateDynamicMethod(MethodInfo methodInfo,out Delegate @delegate)
{
if (methodInfo.DeclaringType == null)
{
throw new ArgumentNullException(nameof(methodInfo.DeclaringType));
}
EmitMethodInfo emitMethodInfo = new EmitMethodInfo();
bool IsTask = IsGenericTask(methodInfo.ReturnType, out var taskGenericsType);
bool IsTaskGenerics = taskGenericsType != null;
DynamicMethod dynamicMethod;
Type returnType;
if (!IsTask)
{
// 普通方法
returnType = typeof(object);
}
else
{
// 异步方法
if (IsTaskGenerics)
{
returnType = typeof(Task