有没有办法泛化Action和Action<T>?
Is there a way to generalise Action and Action<T>?
所以我有一个扩展方法,允许我在执行操作时记录一些东西。实现是这样的:
public static Action Log(this Action action, string log) {
return (() => {
Console.WriteLine(log);
action();
});
}
但我想允许动作也是 Action<T>
。有没有办法概括这一点,以便 log
被记录下来,但它不会更改操作的签名?
或者我需要 2 种方法,一种用于 Action
,一种用于 Action<T>
?
您将需要两种方法,因为 Action
和 Action<T>
在这种情况下彼此不兼容。
如果 Action
实际上是 Action<void>
来启用此行为,那将很有用,但事实并非如此。
您可以使用类型 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
您需要单独的方法,但您可以根据另一个来实现一个以减少代码重复:
鉴于您现有的 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);
}
所以我有一个扩展方法,允许我在执行操作时记录一些东西。实现是这样的:
public static Action Log(this Action action, string log) {
return (() => {
Console.WriteLine(log);
action();
});
}
但我想允许动作也是 Action<T>
。有没有办法概括这一点,以便 log
被记录下来,但它不会更改操作的签名?
或者我需要 2 种方法,一种用于 Action
,一种用于 Action<T>
?
您将需要两种方法,因为 Action
和 Action<T>
在这种情况下彼此不兼容。
如果 Action
实际上是 Action<void>
来启用此行为,那将很有用,但事实并非如此。
您可以使用类型 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
您需要单独的方法,但您可以根据另一个来实现一个以减少代码重复:
鉴于您现有的 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);
}