2024-10-10 10:45:53 +08:00
|
|
|
|
using Serein.Library.Utils;
|
|
|
|
|
|
using System;
|
2024-10-27 00:54:10 +08:00
|
|
|
|
using System.Reflection;
|
2024-10-10 10:45:53 +08:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using static Serein.Library.Utils.EmitHelper;
|
|
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
namespace Serein.Library
|
2024-10-10 10:45:53 +08:00
|
|
|
|
{
|
2024-10-10 16:49:37 +08:00
|
|
|
|
/// <summary>
|
2025-07-26 19:36:54 +08:00
|
|
|
|
/// 通过 Emit 创建委托,代替反射调用方法,实现高性能的动态调用。
|
2024-10-11 19:31:34 +08:00
|
|
|
|
/// 一般情况下你无须内部细节,只需要调用 Invoke() 方法即可。
|
2024-10-10 16:49:37 +08:00
|
|
|
|
/// </summary>
|
2024-10-10 10:45:53 +08:00
|
|
|
|
public class DelegateDetails
|
|
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
private readonly EmitType emitType = EmitType.None;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建的委托类型
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public enum EmitType
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 默认
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
None,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 方法调用
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
MethodInvoke,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 字段赋值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
FieldSetter,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 字段取值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
FieldGetter,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 属性赋值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
PropertySetter,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 属性取值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
PropertyGetter,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 集合取值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
CollectionGetter,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 集合赋值
|
|
|
|
|
|
/// </summary>
|
2025-07-31 11:21:49 +08:00
|
|
|
|
CollectionSetter,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 数组创建
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
ArrayCreate,
|
2025-07-26 19:36:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-30 21:15:07 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 表示方法的类型
|
|
|
|
|
|
/// </summary>
|
2025-07-26 19:36:54 +08:00
|
|
|
|
public enum GSType
|
2025-07-30 21:15:07 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取值
|
|
|
|
|
|
/// </summary>
|
2025-07-26 19:36:54 +08:00
|
|
|
|
Get,
|
2025-07-30 21:15:07 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置值
|
|
|
|
|
|
/// </summary>
|
2025-07-26 19:36:54 +08:00
|
|
|
|
Set,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-10-27 00:54:10 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据方法信息构建Emit委托
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="methodInfo"></param>
|
|
|
|
|
|
public DelegateDetails(MethodInfo methodInfo)
|
|
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
emitType = EmitType.MethodInvoke;
|
2026-01-27 17:33:48 +08:00
|
|
|
|
var emitMethodType = EmitHelper.CreateMethod(methodInfo, out var emitDelegate);
|
2024-12-20 23:39:29 +08:00
|
|
|
|
_emitMethodInfo = emitMethodType;
|
2024-10-27 00:54:10 +08:00
|
|
|
|
_emitDelegate = emitDelegate;
|
2025-07-26 19:36:54 +08:00
|
|
|
|
methodType = _emitMethodInfo.EmitMethodType;
|
2025-06-02 16:38:37 +08:00
|
|
|
|
if (_emitDelegate is Func<object, object[], Task<object>> hasResultTask)
|
|
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
this.methodHasResultTask = hasResultTask;
|
2025-06-02 16:38:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
else if (_emitDelegate is Func<object, object[], Task> task)
|
|
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
this.methodTask = task;
|
2025-06-02 16:38:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
else if (_emitDelegate is Func<object, object[], object> func)
|
|
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
this.methodInvoke = func;
|
2025-06-02 16:38:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-26 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据字段信息构建Emit取/赋值委托
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="fieldInfo">字段信息</param>
|
|
|
|
|
|
/// <param name="gsType">是否为 get,如果不是,则为 set</param>
|
|
|
|
|
|
public DelegateDetails(FieldInfo fieldInfo, GSType gsType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (gsType == GSType.Get)
|
|
|
|
|
|
{
|
|
|
|
|
|
emitType = EmitType.FieldGetter;
|
|
|
|
|
|
getter = EmitHelper.CreateFieldGetter(fieldInfo);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (gsType == GSType.Set)
|
|
|
|
|
|
{
|
|
|
|
|
|
emitType = EmitType.FieldSetter;
|
|
|
|
|
|
setter = EmitHelper.CreateFieldSetter(fieldInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotSupportedException("错误的构建类型");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据字段信息构建Emit取/赋值委托
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="propertyInfo">字段信息</param>
|
|
|
|
|
|
/// <param name="gsType">是否为 get,如果不是,则为 set</param>
|
|
|
|
|
|
public DelegateDetails(PropertyInfo propertyInfo, GSType gsType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (gsType == GSType.Get)
|
|
|
|
|
|
{
|
|
|
|
|
|
emitType = EmitType.PropertyGetter;
|
|
|
|
|
|
getter = EmitHelper.CreatePropertyGetter(propertyInfo);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (gsType == GSType.Set)
|
|
|
|
|
|
{
|
|
|
|
|
|
emitType = EmitType.PropertySetter;
|
|
|
|
|
|
setter = EmitHelper.CreatePropertySetter(propertyInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotSupportedException("错误的构建类型");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 目前提供了创建集合取值/赋值委托
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="type">类型信息</param>
|
2025-07-30 21:15:07 +08:00
|
|
|
|
/// <param name="emitType">操作类型</param>
|
2025-07-31 23:59:31 +08:00
|
|
|
|
public DelegateDetails(Type type, EmitType emitType, Type? itemType = null)
|
2025-07-26 19:36:54 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (emitType == EmitType.CollectionSetter)
|
|
|
|
|
|
{
|
2025-07-29 14:51:14 +08:00
|
|
|
|
this.emitType = EmitType.CollectionSetter;
|
2025-07-26 19:36:54 +08:00
|
|
|
|
collectionSetter = EmitHelper.CreateCollectionSetter(type);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (emitType == EmitType.CollectionGetter)
|
|
|
|
|
|
{
|
2025-07-29 14:51:14 +08:00
|
|
|
|
this.emitType = EmitType.CollectionGetter;
|
2025-07-31 23:59:31 +08:00
|
|
|
|
collectionGetter = EmitHelper.CreateCollectionGetter(type, itemType);
|
2025-07-26 19:36:54 +08:00
|
|
|
|
}
|
2025-07-31 11:21:49 +08:00
|
|
|
|
else if (emitType == EmitType.ArrayCreate)
|
|
|
|
|
|
{
|
|
|
|
|
|
Func<int, object> func = EmitHelper.CreateArrayFactory(type);
|
|
|
|
|
|
this.arrayCreatefunc = func;
|
|
|
|
|
|
this.emitType = EmitType.ArrayCreate;
|
|
|
|
|
|
}
|
2025-07-26 19:36:54 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotSupportedException("错误的构建类型");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-31 11:21:49 +08:00
|
|
|
|
|
2025-07-26 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Func<object,object, object> collectionGetter= null;
|
|
|
|
|
|
private Action<object,object, object> collectionSetter = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Func<object, object> getter = null;
|
|
|
|
|
|
private Action<object, object> setter = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Func<object, object[], Task<object>> methodHasResultTask = null;
|
|
|
|
|
|
private Func<object, object[], Task> methodTask = null;
|
|
|
|
|
|
private Func<object, object[], object> methodInvoke = null;
|
2025-06-02 16:38:37 +08:00
|
|
|
|
|
2025-07-31 11:21:49 +08:00
|
|
|
|
private Func<int, object> arrayCreatefunc = null;
|
|
|
|
|
|
|
2025-03-14 16:04:06 +08:00
|
|
|
|
|
2024-11-04 23:30:52 +08:00
|
|
|
|
/*/// <summary>
|
2024-10-15 10:55:41 +08:00
|
|
|
|
/// 更新委托方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="EmitMethodType"></param>
|
|
|
|
|
|
/// <param name="EmitDelegate"></param>
|
2024-10-10 10:45:53 +08:00
|
|
|
|
public void Upload(EmitMethodType EmitMethodType, Delegate EmitDelegate)
|
|
|
|
|
|
{
|
|
|
|
|
|
_emitMethodType = EmitMethodType;
|
|
|
|
|
|
_emitDelegate = EmitDelegate;
|
2024-11-04 23:30:52 +08:00
|
|
|
|
}*/
|
|
|
|
|
|
|
2024-10-10 10:45:53 +08:00
|
|
|
|
private Delegate _emitDelegate;
|
2024-12-20 23:39:29 +08:00
|
|
|
|
private EmitMethodInfo _emitMethodInfo;
|
2025-07-26 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private EmitMethodType methodType;
|
2024-12-20 23:39:29 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 该Emit委托的相应信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public EmitMethodInfo EmitMethodInfo => _emitMethodInfo;
|
2024-10-15 10:55:41 +08:00
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
///// <summary>
|
|
|
|
|
|
///// <para>普通方法:Func<object,object[],object></para>
|
|
|
|
|
|
///// <para>异步方法:Func<object,object[],Task></para>
|
|
|
|
|
|
///// <para>异步有返回值方法:Func<object,object[],Task<object>></para>
|
|
|
|
|
|
///// </summary>
|
|
|
|
|
|
//public Delegate EmitDelegate { get => _emitDelegate; }
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
|
///// 表示Emit构造的委托类型
|
|
|
|
|
|
///// </summary>
|
|
|
|
|
|
//public EmitMethodType EmitMethodType { get => _emitMethodType; }
|
2024-10-10 20:52:19 +08:00
|
|
|
|
|
2024-12-20 23:39:29 +08:00
|
|
|
|
|
2025-07-26 19:36:54 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// <para>使用的实例必须能够正确调用该委托,传入的参数也必须符合方法入参信息。</para>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="instance">拥有符合委托签名的实例</param>
|
|
|
|
|
|
/// <param name="args">如果不需要入参,也需要传入一个空数组,而不能为 null</param>
|
|
|
|
|
|
/// <returns>void方法、setter自动返回null</returns>
|
|
|
|
|
|
public async Task<object> InvokeAsync(object instance, object[] args)
|
2024-12-20 23:39:29 +08:00
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
if (emitType == EmitType.MethodInvoke)
|
|
|
|
|
|
{
|
|
|
|
|
|
return await MethodInvoke(instance, args);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (emitType == EmitType.PropertyGetter || emitType == EmitType.FieldGetter)
|
|
|
|
|
|
{
|
|
|
|
|
|
return getter(instance);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (emitType == EmitType.PropertySetter || emitType == EmitType.FieldSetter)
|
2024-12-20 23:39:29 +08:00
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
setter(instance, args[0]);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (emitType == EmitType.CollectionGetter)
|
|
|
|
|
|
{
|
|
|
|
|
|
return collectionGetter(instance, args[0]);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (emitType == EmitType.CollectionSetter)
|
|
|
|
|
|
{
|
|
|
|
|
|
collectionSetter(instance, args[0], args[1]);
|
|
|
|
|
|
return null;
|
2024-12-20 23:39:29 +08:00
|
|
|
|
}
|
2025-07-31 11:21:49 +08:00
|
|
|
|
else if(emitType == EmitType.ArrayCreate)
|
2024-12-20 23:39:29 +08:00
|
|
|
|
{
|
2025-07-31 11:21:49 +08:00
|
|
|
|
if(args[0] is int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
return arrayCreatefunc(count);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-12-20 23:39:29 +08:00
|
|
|
|
}
|
2025-07-31 11:21:49 +08:00
|
|
|
|
throw new NotSupportedException("当前委托类型不支持 InvokeAsync 方法。请使用其他方法调用。");
|
|
|
|
|
|
|
2024-12-20 23:39:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-26 19:36:54 +08:00
|
|
|
|
private async Task<object> MethodInvoke(object instance, object[] args)
|
2024-10-10 20:52:19 +08:00
|
|
|
|
{
|
2024-10-27 00:54:10 +08:00
|
|
|
|
if (args is null)
|
2024-10-15 10:55:41 +08:00
|
|
|
|
{
|
2024-10-20 12:10:57 +08:00
|
|
|
|
args = Array.Empty<object>();
|
2024-10-15 10:55:41 +08:00
|
|
|
|
}
|
2025-07-26 19:36:54 +08:00
|
|
|
|
if (_emitMethodInfo.IsStatic)
|
2024-12-20 23:39:29 +08:00
|
|
|
|
{
|
|
|
|
|
|
instance = null;
|
|
|
|
|
|
}
|
2024-10-10 20:52:19 +08:00
|
|
|
|
object result = null;
|
2025-07-26 19:36:54 +08:00
|
|
|
|
if (methodType == EmitMethodType.Func)
|
2024-10-10 20:52:19 +08:00
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
result = methodInvoke.Invoke(instance, args);
|
2025-06-02 16:38:37 +08:00
|
|
|
|
|
2024-10-10 20:52:19 +08:00
|
|
|
|
}
|
2025-07-26 19:36:54 +08:00
|
|
|
|
else if (methodType == EmitMethodType.TaskHasResult)
|
2024-10-10 20:52:19 +08:00
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
result = await methodHasResultTask(instance, args);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (methodType == EmitMethodType.Task)
|
2024-12-09 22:57:06 +08:00
|
|
|
|
{
|
2025-07-26 19:36:54 +08:00
|
|
|
|
await methodTask(instance, args);
|
2025-06-02 16:38:37 +08:00
|
|
|
|
result = null;
|
2024-12-09 22:57:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException("创建了非预期委托(应该不会出现)");
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
2024-10-10 20:52:19 +08:00
|
|
|
|
}
|
2025-07-26 19:36:54 +08:00
|
|
|
|
|
2024-10-10 10:45:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|