using Serein.Library.Utils; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using static Serein.Library.Utils.EmitHelper; namespace Serein.Library { /// /// 通过 Emit 创建委托,代替反射调用方法,实现高性能的动态调用。 /// 一般情况下你无须内部细节,只需要调用 Invoke() 方法即可。 /// public class DelegateDetails { private readonly EmitType emitType = EmitType.None; /// /// 创建的委托类型 /// public enum EmitType { /// /// 默认 /// None, /// /// 方法调用 /// MethodInvoke, /// /// 字段赋值 /// FieldSetter, /// /// 字段取值 /// FieldGetter, /// /// 属性赋值 /// PropertySetter, /// /// 属性取值 /// PropertyGetter, /// /// 集合取值 /// CollectionGetter, /// /// 集合赋值 /// CollectionSetter } /// /// 表示方法的类型 /// public enum GSType { /// /// 获取值 /// Get, /// /// 设置值 /// Set, } /// /// 根据方法信息构建Emit委托 /// /// public DelegateDetails(MethodInfo methodInfo) { emitType = EmitType.MethodInvoke; var emitMethodType = EmitHelper.CreateDynamicMethod(methodInfo, out var emitDelegate); _emitMethodInfo = emitMethodType; _emitDelegate = emitDelegate; methodType = _emitMethodInfo.EmitMethodType; if (_emitDelegate is Func> hasResultTask) { this.methodHasResultTask = hasResultTask; } else if (_emitDelegate is Func task) { this.methodTask = task; } else if (_emitDelegate is Func func) { this.methodInvoke = func; } else { throw new NotSupportedException(); } } /// /// 根据字段信息构建Emit取/赋值委托 /// /// 字段信息 /// 是否为 get,如果不是,则为 set 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("错误的构建类型"); } } /// /// 根据字段信息构建Emit取/赋值委托 /// /// 字段信息 /// 是否为 get,如果不是,则为 set 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("错误的构建类型"); } } /// /// 目前提供了创建集合取值/赋值委托 /// /// 类型信息 /// 操作类型 public DelegateDetails(Type type, EmitType emitType) { if (emitType == EmitType.CollectionSetter) { this.emitType = EmitType.CollectionSetter; collectionSetter = EmitHelper.CreateCollectionSetter(type); } else if (emitType == EmitType.CollectionGetter) { this.emitType = EmitType.CollectionGetter; collectionGetter = EmitHelper.CreateCollectionGetter(type); } else { throw new NotSupportedException("错误的构建类型"); } } private Func collectionGetter= null; private Action collectionSetter = null; private Func getter = null; private Action setter = null; private Func> methodHasResultTask = null; private Func methodTask = null; private Func methodInvoke = null; /*/// /// 更新委托方法 /// /// /// public void Upload(EmitMethodType EmitMethodType, Delegate EmitDelegate) { _emitMethodType = EmitMethodType; _emitDelegate = EmitDelegate; }*/ private Delegate _emitDelegate; private EmitMethodInfo _emitMethodInfo; private EmitMethodType methodType; /// /// 该Emit委托的相应信息 /// public EmitMethodInfo EmitMethodInfo => _emitMethodInfo; ///// ///// 普通方法:Func<object,object[],object> ///// 异步方法:Func<object,object[],Task> ///// 异步有返回值方法:Func<object,object[],Task<object>> ///// //public Delegate EmitDelegate { get => _emitDelegate; } ///// ///// 表示Emit构造的委托类型 ///// //public EmitMethodType EmitMethodType { get => _emitMethodType; } /// /// 使用的实例必须能够正确调用该委托,传入的参数也必须符合方法入参信息。 /// /// 拥有符合委托签名的实例 /// 如果不需要入参,也需要传入一个空数组,而不能为 null /// void方法、setter自动返回null public async Task InvokeAsync(object instance, object[] args) { 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) { 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; } else { throw new NotSupportedException("当前委托类型不支持 InvokeAsync 方法。请使用其他方法调用。"); } } private async Task MethodInvoke(object instance, object[] args) { if (args is null) { args = Array.Empty(); } if (_emitMethodInfo.IsStatic) { instance = null; } object result = null; if (methodType == EmitMethodType.Func) { result = methodInvoke.Invoke(instance, args); } else if (methodType == EmitMethodType.TaskHasResult) { result = await methodHasResultTask(instance, args); } else if (methodType == EmitMethodType.Task) { await methodTask(instance, args); result = null; } else { throw new NotImplementedException("创建了非预期委托(应该不会出现)"); } return result; } } }