如何避免重复接受 Func<T, int> 作为参数的方法的多个重写
How to avoid repetition with multiple overrides of method accepting Func<T, int> as parameters
我想要一个 "generic" - 也就是说,如果可能的话,一个具有单一签名的方法 - 而不是下面的 copy/paste 代码。
我的目标是 "wrap" 来自第三方 DLL 的方法 Spy Double
int spy(Func<int> method)
{
methodCalls.Add(method.Method.Name);
return method.Invoke();
}
int spy(Func<string, int> method, string arg)
{
methodCalls.Add(method.Method.Name);
return method.Invoke(arg);
}
private int spy(Func<int, int> method, int arg)
{
methodCalls.Add(method.Method.Name);
return method.Invoke(arg);
}
您看到了问题:我有几乎相同的方法块...有没有办法避免这种情况并仍然完成所需的行为?
好吧,您可以先将它们设为通用:
public TResult Spy<TResult>(Func<TResult> method)
{
methodCalls.Add(method.Method.Name);
return method();
}
public TResult Spy<TArg, TResult>(Func<TArg, TResult> method, TArg arg)
{
methodCalls.Add(method.Method.Name);
return method(arg);
}
public TResult Spy<TArg1, TArg2, TResult>
(Func<TArg1, TArg2, TResult> method, TArg1 arg1, TArg2 arg2)
{
methodCalls.Add(method.Method.Name);
return method(arg1, arg2);
}
...
这至少意味着您只需要与要处理的最大参数数量一样多的重载。在不丢失编译时类型安全的情况下,您将无法轻易地做得比这更好。
首先,您需要用于要监视的 Func
和 Action
委托的通用方法。你需要这些方法来实现漂亮的强类型API。您还需要一个接受 Delegate
和参数列表的私有泛型方法。此方法将进行调用和记录:
public TResult Spy<TResult> (Func<TResult> method)
{
return Spy<TResult>((Delegate)method);
}
public TResult Spy<T1, TResult> (Func<T1, TResult> method, T1 arg1)
{
return Spy<TResult>((Delegate)method, arg1);
}
private TResult Spy<TResult> (Delegate method, params object[] args)
{
methodCalls.Add(method.Method.Name);
return (TResult)method.Method.Invoke(method.Target, args);
}
现在您可以传递带有零个或一个参数的任何方法,执行它们并记录方法名称,而不会出现任何重复。
基于您的主要目标
to have a "generic" - that is, a method with a single signature if possible instead of this rather copy/paste code below.
您可以尝试关注
object SpyUniversal(Delegate method, object[] args)
{
methodCalls.Add(method.Method.Name);
return method.Method.Invoke(null, args);
}
请注意,如前所述,您正在失去编译时类型安全性。
我想要一个 "generic" - 也就是说,如果可能的话,一个具有单一签名的方法 - 而不是下面的 copy/paste 代码。
我的目标是 "wrap" 来自第三方 DLL 的方法 Spy Double
int spy(Func<int> method)
{
methodCalls.Add(method.Method.Name);
return method.Invoke();
}
int spy(Func<string, int> method, string arg)
{
methodCalls.Add(method.Method.Name);
return method.Invoke(arg);
}
private int spy(Func<int, int> method, int arg)
{
methodCalls.Add(method.Method.Name);
return method.Invoke(arg);
}
您看到了问题:我有几乎相同的方法块...有没有办法避免这种情况并仍然完成所需的行为?
好吧,您可以先将它们设为通用:
public TResult Spy<TResult>(Func<TResult> method)
{
methodCalls.Add(method.Method.Name);
return method();
}
public TResult Spy<TArg, TResult>(Func<TArg, TResult> method, TArg arg)
{
methodCalls.Add(method.Method.Name);
return method(arg);
}
public TResult Spy<TArg1, TArg2, TResult>
(Func<TArg1, TArg2, TResult> method, TArg1 arg1, TArg2 arg2)
{
methodCalls.Add(method.Method.Name);
return method(arg1, arg2);
}
...
这至少意味着您只需要与要处理的最大参数数量一样多的重载。在不丢失编译时类型安全的情况下,您将无法轻易地做得比这更好。
首先,您需要用于要监视的 Func
和 Action
委托的通用方法。你需要这些方法来实现漂亮的强类型API。您还需要一个接受 Delegate
和参数列表的私有泛型方法。此方法将进行调用和记录:
public TResult Spy<TResult> (Func<TResult> method)
{
return Spy<TResult>((Delegate)method);
}
public TResult Spy<T1, TResult> (Func<T1, TResult> method, T1 arg1)
{
return Spy<TResult>((Delegate)method, arg1);
}
private TResult Spy<TResult> (Delegate method, params object[] args)
{
methodCalls.Add(method.Method.Name);
return (TResult)method.Method.Invoke(method.Target, args);
}
现在您可以传递带有零个或一个参数的任何方法,执行它们并记录方法名称,而不会出现任何重复。
基于您的主要目标
to have a "generic" - that is, a method with a single signature if possible instead of this rather copy/paste code below.
您可以尝试关注
object SpyUniversal(Delegate method, object[] args)
{
methodCalls.Add(method.Method.Name);
return method.Method.Invoke(null, args);
}
请注意,如前所述,您正在失去编译时类型安全性。