我想要一个代理,我可以将其存储在一个变量中供以后使用,该代码具有自定义数量的自定义参数。我的意思是,我想用不同的返回类型和不同的参数推出不同的方法。例如:
public double Sum (double a, double b) {return a + b;}
public char GetFirst (string a) {return a[0];}
public bool canFlipTable (object[] thingsOnIt) {return thingsOnIt.Length <= 3;}
DoTheThing<double> thing1 = new DoTheThing<double>(Sum);
DoTheThing<char> thing2 = new DoTheThing<char>(GetFirst);
DoTheThing<bool> thing3 = new DoTheThing<bool>(canFlipTable);
thing1.Call(10.3, 5.6); //15.9
thing2.Call("Hello World"); //'H'
thing3.Call(new object[] {new Lamp(), new Laptop(), new CoffeMug()}); //true
我已经找到了返回值和调用方法,但是我在存储方法时遇到了问题
如果我使用“public DoTheThing(Action method)”,它说,参数不匹配 我甚至尝试过使用“params object [] p”作为参数的代理,但它也不起作用
编辑: 我忘了告诉,方法将始终具有返回类型和至少1个参数
编辑2: 我的目标是创建一个包装器类,它从非常昂贵的方法缓存输出,如果再次调用相同的东西,它将返回缓存的值。 当然我可以通过一个接口来解决这个问题,但是我想用不能简单编辑的类来做这个,我也想让它变得灵活,所以在我调用方法的同一个地方放置缓存不是选项。
我的代码是:
public class DoTheThing <T>
{
public delegate T Method(params object[] parameters);
Func<T> method;
ParameterInfo[] pInfo;
public DoTheThing (Method method)
{
this.method = method;
Type type = typeof(Method);
MethodInfo info = type.GetMethod ("Invoke");
if (info.ReturnType != typeof(T)) {
throw new Exception ("Type of DoTheThing and method don't match");
}
pInfo = info.GetParameters ();
}
public T Call (params object[] parameters) {
if (parameters.Length != pInfo.Length) {
throw new Exception ("Wrong number of arguments, " + parameters.Length + " instead of " + pInfo.Length);
return default(T);
}
for (int i = 0; i < parameters.Length; i++) {
if (pInfo[i].ParameterType != parameters[i].GetType()) {
throw new Exception ("Wrong parameter: " + parameters [i].GetType () + " instead of " + pInfo [i].ParameterType + " at position: " + i);
return default(T);
}
}
return (T)method.DynamicInvoke (parameters);
}
}
答案 0 :(得分:1)
在试图弄清楚如何做之前,我真的会质疑导致我有这样一种代表的问题。我敢打赌,如果我更了解情况,就会有一个解决方案可以消除你的要求。
说到这里,委托是从MulticastDelegate继承的类。实际上,当您声明委托时,您正在创建一个新的类类型,其中MulticastDelegate作为其基类。这意味着以下代码有效:
public static double Sum(double a, double b)
{
return a + b;
}
public static string SayHello()
{
return "Hello";
}
static void Main(string[] args)
{
MulticastDelegate mydel = new Func<double, double, double>(Sum);
var ret = mydel.DynamicInvoke(1, 2);
System.Console.WriteLine(ret);
mydel = new Func<string>(SayHello);
ret = mydel.DynamicInvoke();
System.Console.WriteLine(ret);
mydel = new Func<string, int, string> ((s, i) => {
return $"Would be {s}, {i} times";
});
ret = mydel.DynamicInvoke("Hello", 5);
System.Console.WriteLine(ret);
}
因为&#34; mydel&#34;变量属于基类类型(MulticastDelegate),我们实际上可以将它与任何类型的委托一起使用,并使用任意参数调用它。如果它们与正在调用的方法不匹配,它将在运行时抛出。