【发布时间】:2020-07-10 20:36:35
【问题描述】:
我正在尝试使用不同的参数类型和返回类型来归档类似“特定事件的注册方法”之类的东西,到目前为止,我的计划是使用泛型实现的。
调用 RegisterMethod 函数后,我需要将给定的“方法”参数存储在列表中,包括其输入类型和输出类型。为了以后使用,我想用注册的类型调用给定的方法。
我现在遇到的问题如下:在服务器上调用 ProcessIncomingRequest 后,我需要将 byte[] 数据反序列化为我在 RegisterMethod 方法中定义的给定类型以及返回类型,以便响应客户端。但我不知道如何在代码中转换这些类型。
struct MethodData
{
public string Name;
public System.Reflection.MethodInfo MethodInfo;
public Type ReturnType;
public Type ArgumentType;
}
class NetworkServer
{
List<MethodData> list = new List<MethodData>();
public void RegisterMethod<In, Out>(string name, Func<NetworkClient, In, Out> method)
{
list.Add(new MethodData()
{
MethodInfo = method.Method,
Name = name,
ReturnType = typeof(Out),
ArgumentType = typeof(In)
});
// Store the method including
// it the return type
// In theory I want to add them to a List/Dictionary
// and re-use the method + types in the
// ProcessIncomingRequest method.
}
public void RegisterMethod<In>(string name, Action<NetworkClient, In> method)
{
list.Add(new MethodData()
{
MethodInfo = method.Method,
Name = name,
ArgumentType = typeof(In),
});
// Same as above, this method doesn't return anything. Its just a call and forget
}
public static void ProcessIncomingRequest(NetworkClient cl, string name, byte[] data)
{
var method = list.SingleOrDefault(x => x.Name.Equals(name));
if(method != NULL)
{
var finalData = Serializer<Tin>(data);
// Tin = it.ArgumentType
// Tout = it.ReturnType
// This is exactly what I would need to archive
var retn = it.MethodInfo.Invoke(null, new[] { cl, finalData });
if(retn != NULL && it.ReturnType != NULL)
cl.Send<Tout>(retn);
}
// name represents the method name in the List
// data represents represents the parameter values
// The generic "Tin" and "Tout is the problem here
}
}
static void main()
{
NetworkServer server = new NetworkServer(9000);
server.RegisterMethod<int, bool>("CheckValue", CheckValue);
server.RegisterMethod<string>("Log", NotifyLogger);
server.Start();
}
// Execute method with received data and return result to client
static bool CheckValue(NetworkClient cl, int value)
{
return value >= 10;
}
// Execute data without the need of any return
static void NotifyLogger(NetworkClient cl, string logger)
{
Console.WriteLine($"Incoming Logger request : {logger}");
MyLogger.Write($"[SERVER] {logger}");
}
【问题讨论】: