我无法防止重复的代码。委托传递为通用参数时调用C#委托方法
目前,我有以下方法:
protected delegate bool CallbackDelegate<T>(T param, out string result);
protected delegate bool CallbackDelegate<T, U>(T param1, U param2, out string result);
protected bool ClientCtrlCallback<T>(T param, CallbackDelegate<T> callbackMethod)
{...}
protected bool ClientCtrlCallback<T,U>(T param1, U param2, CallbackDelegate<T,U> callbackMethod)
{...}
两个ClientCtrlCallback方法具有相同的代码(检查沟通渠道的有效性,try-catch块,获取锁等),在调用CallbackDelegate方法周围建。
我一直在试图合并这些ClientCtrl方法,但没有成功,因为委托约束是不被允许的。这是据我得到:(为清楚起见移除不必要的代码)
protected delegate bool CallbackDelegate1<T>(T param, out string result);
protected delegate bool CallbackDelegate2<T, U>(T param1, U param2, out string result);
protected const string METHOD_MY_DELEGATE1 = "CallbackDelegate1";
protected const string METHOD_MY_DELEGATE2 = "CallbackDelegate2";
protected interface ParameterSet { };
protected class OneParameter<T>: ParameterSet { public T p1; };
protected class TwoParameters<T,U> : ParameterSet { public T p1; public U p2; };
protected bool ClientCtrlCallback<D,T,U>(ParameterSet parameterset, D callbackMethod, string successLog = null) // where MyDelegate : delegate //not allowed
{
// delegate constrained is not allowed, so check it here
if (!typeof(D).IsSubclassOf(typeof(Delegate)))
return false;
// check name of method (this works)
string methodName = (callbackMethod as Delegate).Method.Name;
// Call the delegate // doesn't work.
string result;
switch (methodName)
{
case METHOD_MY_DELEGATE1:
// doesnt work
//(callbackMethod as Delegate)((parameterset as OneParameter<T>).p1, out result);
break;
case METHOD_MY_DELEGATE2:
// doesnt work
//(callbackMethod as Delegate)((parameterset as TwoParameters<T, U>).p1, (parameterset as TwoParameters<T, U>).p2, out result); // doesnt work
break;
}
return true;
}
它开始变得丑陋了参数类。交换机比较代表的姓名会变得更糟(我也不喜欢每个人都给他们一个不同的名字)。然后,当我想调用Delegate的方法时,总是有麻烦:编译时错误Method name expected
我不明白为什么我可以从Delegate获取方法名称,但不调用Delegate的方法。我错过了什么大事?
也许用类,接口,虚拟方法和所有爵士乐来代替整个事物? –
不要这样做。如果在这两种方法中存在多余的重复代码,则将重复的代码抽象为辅助方法。但不要更改两个方法的签名,然后尝试在运行时强制实现类型系统。更一般地说:人们花费太多时间担心小的重复。正如你所发现的那样,它们的重复数据删除非常昂贵,而且这种努力可能会更好地用于编写测试,寻找错误,设计下一个版本等等。 –
尝试使用Action <>? – lindexi