/// <summary> /// 调用函数 /// </summary> /// <param name="serializer">命令行反序列器</param> /// <param name="methodSpecs">函数的参数说明</param> /// <param name="obj">调用函数时的this对象</param> /// <param name="argList">命令行参数,本集合会被修改,调用完毕后集合内是剩余的命令行参数</param> /// <param name="beforeInvoke">获取到函数参数后调用函数前触发</param> /// <returns>函数返回值</returns> public static object?InvokeMethod( CommandLineSerializer serializer, MethodSpecs methodSpecs, object?obj, LinkedList <string> argList, Action <ParameterInfo[], object?[]>?beforeInvoke) { var method = methodSpecs.Method; var paramInfos = method.GetParameters(); var length = paramInfos.Length; var parameters = new object?[length]; var touchedIndexes = new bool[length]; serializer.Deserialize(argList, methodSpecs, (spec, paramObj) => { if (methodSpecs.TryGetParameterIndex(spec, out var index) && 0 <= index && index < length) { parameters[index] = paramObj; touchedIndexes[index] = true; } }); // 设置函数参数自身的默认值 for (var i = 0; i < length; ++i) { var paramInfo = paramInfos[i]; if (!touchedIndexes[i]) { if (paramInfo.DefaultValue == DBNull.Value) { throw new InvalidOperationException($"Lack of {i + 1}th non-default parameter: {paramInfo.Name}."); } parameters[i] = paramInfo.DefaultValue; } } beforeInvoke?.Invoke(paramInfos, parameters); if (method is ConstructorInfo constructorInfo) { return(constructorInfo.Invoke(parameters)); } return(method.Invoke(obj, parameters)); }
public ObjectSpecs?GetObjectSpecs(Type objType) { var memberSpecs = new MemberSpecs(objType); memberSpecs.Init(); object?deserializeObj = null; object?serializeObj = null; return(new ObjectSpecs( memberSpecs, (serializer, argList) => { var constructorSpecs = new MethodSpecs(FindConstructor(objType)); constructorSpecs.Init(); deserializeObj = MethodInvoker.InvokeMethod(serializer, constructorSpecs, null, argList); Debug.Assert(deserializeObj != null); return deserializeObj; }, (spec, value) => { memberSpecs.TryGetMember(spec, out var memberInfo); memberInfo.SetValue(deserializeObj, value); }, (_, _) => deserializeObj, (_, obj) => serializeObj = obj, spec => { memberSpecs.TryGetMember(spec, out var memberInfo); return memberInfo.GetValue(serializeObj); }, (_, _) => { })); }
/// <summary> /// 调用函数 /// </summary> /// <param name="serializer">命令行反序列器</param> /// <param name="methodSpecs">函数的参数说明</param> /// <param name="obj">调用函数时的this对象</param> /// <param name="argList">命令行参数,本集合会被修改,调用完毕后集合内是剩余的命令行参数</param> /// <returns>函数返回值</returns> public static object?InvokeMethod( CommandLineSerializer serializer, MethodSpecs methodSpecs, object?obj, LinkedList <string> argList) => InvokeMethod(serializer, methodSpecs, obj, argList, null);