我正在开发一个项目,允许客户端在服务器上为其特定实例调用远程函数。基本上,当客户端连接时,它将获得自己的共享类实例,然后客户端将使用方法返回类型的名称和参数+它们的预期类型来调用服务器。
我正在进行的方式是创建一个Prototypes类,并在其中创建Delegates来表示Server的共享类中的Method原型。
我将处理所有这些的方式是当客户端连接到服务器时,客户端将遍历Prototypes类并获取所有Fields,然后它将尝试将所有Fields内部链接到一个泛型方法来处理任何函数被调用后,该函数将获得它声明的返回类型&参数信息等,然后将其发送到服务器。
我的第一个想法是使用
params object[] param
但是,如果我说喂它,那么Delegate.CreateDelegate会在运行时出错:
public delegate string TestDelegate(string s1, string s2, string[] s3);
public TestDelegate Test;
但是,如果我创建了所有委托链接回的方法的多个重载,那么它可以正常工作:
public T handleFunc<T>(object param)
{
Console.WriteLine(param as string);
return default(T);
}
public T handleFunc<T>(object param, object param2)
{
Console.WriteLine(param as string);
return default(T);
}
public T handleFunc<T>(object param, object param2, object param3)
{
Console.WriteLine((param3 as string[])[0]);
return default(T);
}
这是我将代理链接到handleFunc方法的当前代码:
private void ValidatePrototypes()
{
var fields = typeof(Prototypes).GetFields();
foreach (FieldInfo field in fields)
{
MethodInfo thisfield = field.FieldType.GetMethods()[0];
ParameterInfo[] pi = thisfield.GetParameters();
var handle = typeof(Client).GetMethod("handleFunc", Array.ConvertAll(pi, s => s.ParameterType));
var lambda = handle.MakeGenericMethod(thisfield.ReturnType);
Delegate del = Delegate.CreateDelegate(field.FieldType, this, lambda);
field.SetValue(Functions, del);
}
Console.WriteLine(Functions.Test("", "", new[] { "Hello" }));
}
我实际上需要一个方法来任何可能的委托(或者最好的变体)链接到并能够从那里处理数据。
我感谢任何回复。
答案 0 :(得分:0)
我认为这可以在不在运行时创建委托的情况下完成:
public interface IService {
string Foo(int x);
}
public class ServerClass : IService {
public string Foo(int x) {
return x.ToString();
}
}
public class ClientStub : IService {
protected ITarget target;
public ClientStub(ITarget target) {
this.target = target;
}
public string Foo(int i) {
return (string)target.Invoke(nameof(Foo), i);
}
}
public interface ITarget {
object Invoke(string methodName, params object[] args);
}
public class RemoteTarget : ITarget {
public object Invoke(string methodName, params object[] args) {
// send params over network and return response
}
}
...
new ClientStub(new RemoteTarget()).Foo();
使用您的方法对此没有任何好处。他们通常在框架中执行的操作是它们在运行时使用反射发射实现ClientStub类,因此您不必手动编写它。