C# – 使用任意数量的自定义参数进行委派

我想要一个代理,我可以将其存储在一个变量中供以后使用,该代码具有自定义数量的自定义参数。 我的意思是,我想用不同的返回类型和不同的参数推出不同的方法。 例如:

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 thing1 = new DoTheThing(Sum); DoTheThing thing2 = new DoTheThing(GetFirst); DoTheThing thing3 = new DoTheThing(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  { public delegate T Method(params object[] parameters); Func 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); } } 

在试图弄清楚如何做之前,我真的会质疑导致我有这样一种代表的问题。 我敢打赌如果我更了解情况,就会有一个解决方案可以消除你的要求。

话虽如此,委托是inheritanceMulticastDelegate的类。 实际上,当您声明委托时,您正在创建一个以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(Sum); var ret = mydel.DynamicInvoke(1, 2); System.Console.WriteLine(ret); mydel = new Func(SayHello); ret = mydel.DynamicInvoke(); System.Console.WriteLine(ret); mydel = new Func ((s, i) => { return $"Would be {s}, {i} times"; }); ret = mydel.DynamicInvoke("Hello", 5); System.Console.WriteLine(ret); } 

因为“mydel”变量属于基类类型(MulticastDelegate),所以我们实际上可以将它与任何类型的委托一起使用,并使用任意参数调用它。 如果它们与正在调用的方法不匹配,它将在运行时抛出。