namespace Serein.NodeFlow { /// /// 显式参数 /// public class ExplicitData { /// /// 索引 /// public int Index { get; set; } /// /// 是否为显式参数 /// public bool IsExplicitData { get; set; } /// /// 显式类型 /// public Type? ExplicitType { get; set; } /// /// 显示类型编号> /// public string ExplicitTypeName { get; set; } /// /// 方法需要的类型 /// public Type DataType { get; set; } /// /// 方法入参参数名称 /// public string ParameterName { get; set; } /// /// 入参值 /// public string DataValue { get; set; } public string[] Items { get; set; } public ExplicitData Clone() => new() { Index = Index, IsExplicitData = IsExplicitData, ExplicitType = ExplicitType, DataType = DataType, ParameterName = ParameterName, ExplicitTypeName = ExplicitTypeName, DataValue = string.IsNullOrEmpty(DataValue) ? string.Empty : DataValue, Items = [.. Items], }; } public class MethodDetails { public MethodDetails Clone() { return new MethodDetails { ActingInstance = ActingInstance, ActingInstanceType = ActingInstanceType, MethodDelegate = MethodDelegate, MethodDynamicType = MethodDynamicType, MethodGuid = Guid.NewGuid().ToString(), MethodTips = MethodTips, ReturnType = ReturnType, MethodName = MethodName, MethodLockName = MethodLockName, ExplicitDatas = ExplicitDatas.Select(it => it.Clone()).ToArray(), }; } /// /// 作用实例 /// public Type ActingInstanceType { get; set; } /// /// 作用实例 /// public object ActingInstance { get; set; } /// /// 方法GUID /// public string MethodGuid { get; set; } /// /// 方法名称 /// public string MethodName { get; set; } /// /// 方法委托 /// public Delegate MethodDelegate { get; set; } /// /// 节点类型 /// public DynamicNodeType MethodDynamicType { get; set; } /// /// 锁名称 /// public string MethodLockName { get; set; } /// /// 方法说明 /// public string MethodTips { get; set; } /// /// 参数内容 /// public ExplicitData[] ExplicitDatas { get; set; } /// /// 出参类型 /// public Type ReturnType { get; set; } public bool IsCanConnect(Type returnType) { if (ExplicitDatas.Length == 0) { // 目标不需要传参,可以舍弃结果? return true; } var types = ExplicitDatas.Select(it => it.DataType).ToArray(); // 检查返回类型是否是元组类型 if (returnType.IsGenericType && IsValueTuple(returnType)) { return CompareGenericArguments(returnType, types); } else { int index = 0; if (types[index] == typeof(DynamicContext)) { index++; if (types.Length == 1) { return true; } } // 被连接节点检查自己需要的参数类型,与发起连接的节点比较返回值类型 if (returnType == types[index]) { return true; } } return false; } /// /// 检查元组类型 /// /// /// private bool IsValueTuple(Type type) { if (!type.IsGenericType) return false; var genericTypeDef = type.GetGenericTypeDefinition(); return genericTypeDef == typeof(ValueTuple<>) || genericTypeDef == typeof(ValueTuple<,>) || genericTypeDef == typeof(ValueTuple<,,>) || genericTypeDef == typeof(ValueTuple<,,,>) || genericTypeDef == typeof(ValueTuple<,,,,>) || genericTypeDef == typeof(ValueTuple<,,,,,>) || genericTypeDef == typeof(ValueTuple<,,,,,,>) || genericTypeDef == typeof(ValueTuple<,,,,,,,>); } private bool CompareGenericArguments(Type returnType, Type[] parameterTypes) { var genericArguments = returnType.GetGenericArguments(); var length = parameterTypes.Length; for (int i = 0; i < genericArguments.Length; i++) { if (i >= length) return false; if (IsValueTuple(genericArguments[i])) { // 如果当前参数也是 ValueTuple,递归检查嵌套的泛型参数 if (!CompareGenericArguments(genericArguments[i], parameterTypes.Skip(i).ToArray())) { return false; } } else if (genericArguments[i] != parameterTypes[i]) { return false; } } return true; } } }