所以我有一个扩展方法,允许我在执行操作时记录某些内容。实现如下:
public static Action Log(this Action action, string log) {
return (() => {
Console.WriteLine(log);
action();
});
}
但我想允许该行动也是Action<T>
。有没有办法概括这一点,以便log
被记录,但它不会改变动作的签名?
或者我需要2种方法,一种用于Action
,另一种用于Action<T>
?
答案 0 :(得分:3)
您需要单独的方法,但您可以在另一方面实现一个方法以减少代码重复:
鉴于您现有的Log(Action action, string log)
,您可以添加:
public static Action<T> Log<T>(this Action<T> action, string log) {
return t => Log(() => action(t), log);
}
或者相反:
public static Action<T> Log(this Action<T> action, string log) {
return t => {
Console.WriteLine(log);
action(t);
});
}
public static Action Log(this Action action, string log) {
return () => Log<object>(t => action(), log);
}
答案 1 :(得分:2)
您需要两种方法,因为Action
和Action<T>
在这种情况下彼此不兼容。
如果Action
实际上Action<void>
启用此行为会很有用,但事实并非如此。
答案 2 :(得分:2)
您可以使用类型Delegate
并为您提供param object[]
操作的参数,如下所示:
public static Action Log(this Delegate action, string log, params object[] args)
{
return () =>
{
Console.WriteLine(log);
action.DynamicInvoke(args);
};
}
你可以像这样使用这个扩展名:
Action<int> testAction = i => Console.WriteLine($"Test: {i}");
testAction.Log("Logging", 42).Invoke();
这导致此输出:
Logging
Test: 42