internal bool RemoteLogin(string password)
{
return (bool)InvokeMethod(new Func<string, bool>(Server.RemoteLogin), password);
}
internal string GetSessionId()
{
return (string)InvokeMethod(new Func<string>(Server.GetSessionId));
}
public object InvokeMethod(Delegate method, params object[] args)
{
return method.DynamicInvoke(args);
}
要调用InvokeMethod,我必须传递一个新的Func&lt; ....&gt ;,添加参数,并将返回值强制转换为适当的类型。是否有更好的(更通用的)方法,例如使用Generics或Reflection?
非常感谢任何帮助。
答案 0 :(得分:3)
您可以使用Func
变体来实现一定程度的强打字 - 以牺牲重复为代价:
public R InvokeMethod<T,R>(Func<T,R> method, T argument)
{
return method(argument);
}
public R InvokeMethod<T1,T2,R>(Func<T1,T2,R> method, T1 argument1, T2 argument2)
{
return method(argument1, argument2);
}
public R InvokeMethod<T1,T2,T3,R>(Func<T1,T2,T3,R> method, T1 argument1, T2 argument2, T3 argument3)
{
return method(argument1, argument2, argument3);
}
等等。
虽然这与您的原始版本一致,但根本不需要处理参数。尝试用这种方式写InvokeMethod
:
public R InvokeMethod<R>(Func<R> method)
{
return method();
}
然后用这种风格调用它:
internal bool RemoteLogin(string password)
{
return InvokeMethod(() => Server.RemoteLogin(password));
}
internal string GetSessionId()
{
return InvokeMethod( () => Server.GetSessionId());
}
这样,您就可以将参数处理留给lambda表达式,只需要编写一次InvokeMethod。
答案 1 :(得分:2)
“在上面的例子中,方法InvokeMethod被简化了。在我的应用程序中,它会对调用进行日志,监视,异常处理等。”
鉴于此评论,我的建议是重做这一点。您可以将操作设为Func<T>
,而不是像这样调用委托:
public T InvokeMethod<T>(Func<T> method)
{
// Add wrapper as needed
return method();
}
然后,当您需要传递参数时,可以使用lambdas调用它:
internal bool RemoteLogin(string password)
{
return InvokeMethod(() => Server.RemoteLogin(password));
}
internal string GetSessionId()
{
return InvokeMethod(Server.GetSessionId);
}
答案 2 :(得分:1)
我同意Reed你真的可以直接调用这个方法并消除一些冗余代码,但如果你在做这些事情时想要那么强大的输入,那么很容易重写InvokeMethod
这样的调用
public static T InvokeMethod<T>(Delegate method, params object[] args)
{
return (T)method.DynamicInvoke(args);
}
然后你上面的电话就变成了:
return InvokeMethod(new Func<string, bool>(Server.RemoteLogin), password);
Boolean
返回类型由方法的返回类型推断。
答案 3 :(得分:1)
static T Invoke<T>(Func<T> method)
{
//Log here
return method();
}
bool RemoteLogin(string password)
{
return Invoke(() => Server.RemoteLogin(password));
}
答案 4 :(得分:1)
附加信息:如果方法没有返回值(例如“void Logout()”),您可以使用Action委托(方法可以具有相同的名称 - &gt; InvokeMethod - &gt;因为签名/参数不同) :
public void InvokeMethod(Action method)
{
method();
}