我可以在 Action 或 Func 代表中使用参数吗?
Posted
技术标签:
【中文标题】我可以在 Action 或 Func 代表中使用参数吗?【英文标题】:Can I use params in Action or Func delegates? 【发布时间】:2011-05-02 20:34:50 【问题描述】:当我尝试在 Action 委托中使用参数时...
private Action<string, params object[]> WriteToLogCallBack;
我收到了这个设计时错误:
类、结构或接口成员声明中的标记“参数”无效
任何帮助!
【问题讨论】:
params 不是类型,即你可以在类型定义中使用ref
?
【参考方案1】:
这个解决方法怎么样?
private Action<string, object[]> writeToLogCallBack;
public void WriteToLogCallBack(string s, params object[] args)
if(writeToLogCallBack!=null)
writeToLogCallBack(s,args);
或者您可以定义自己的委托类型:
delegate void LogAction(string s, params object[] args);
【讨论】:
如何用 lambda 调用它?【参考方案2】:C# 中不能使用可变类型参数。
这就是为什么会有很多 Action<...>
、Func<...>
和 Tuple<...>
的声明,例如。不过,这将是一个有趣的功能。 C++0x has them.
【讨论】:
不确定它与泛型(相对于模板)的效果如何。【参考方案3】:你可以试试这个。它允许任意数量的参数,如果您传递错误数量或类型的参数,您将收到编译时错误。
public delegate T ParamsAction<T>(params object[] oArgs);
public static T LogAction<T>(string s, ParamsAction<T> oCallback)
Log(s);
T result = oCallback();
return T;
Foo foo = LogAction<Foo>("Hello world.", aoArgs => GetFoo(1,"",'',1.1));
【讨论】:
这是一个非常好的方法......干得好,先生 Bryan 这里有一段很棒的代码。我在上面的代码中添加了一个小扩展,以显示如何包装多个方法调用。我正在使用它将包含数据库调用的多个方法包装到一个事务中。谢谢布莱恩 :-) 这应该返回结果而不是 T 吗? 如果你做不到LogAction<Foo>("Hello world.", (p1,p2,p3) => GetFoo(p1,p2,p3));
还有什么意义???减去....【参考方案4】:
您可以在委托的实际声明中使用params
,但不能在类型为 one 时使用。 Action 的泛型参数只是类型,而不是调用委托时要传递的实际参数。 params 不是类型,而是关键字。
【讨论】:
【参考方案5】:我对 Bryan 的上述代码做了一个小的扩展,以展示如何包装多个方法调用。 我正在使用它来将包含数据库调用的多个方法包装到一个事务中。 谢谢布莱恩 :-) (你可以在LINQPad中运行以下命令进行测试)
//Wrapper code
public delegate void MyAction(params object[] objArgs);
public static void RunActions(params MyAction[] actnArgs)
Console.WriteLine("WrapperBefore: Begin transaction code\n");
actnArgs.ToList().ForEach( actn => actn() );
Console.WriteLine("\nWrapperAfter: Commit transaction code");
//Methods being called
public void Hash (string s, int i, int j) => Console.WriteLine(" Hash-method call: " + s + "###" + i.ToString() + j.ToString());
public void Slash (int i, string s) => Console.WriteLine(" Slash-method call: " + i.ToString()+ @"////" + s);
//Actual calling code
void Main()
RunActions( objArgs => Hash("One", 2, 1)
,objArgs => Slash(3, "four") );
//Resulting output:
//
// WrapperBefore: Begin transaction code
//
// Hash-method call: One###21
// Slash-method call: 3////four
//
// WrapperAfter: Commit transaction code
【讨论】:
以上是关于我可以在 Action 或 Func 代表中使用参数吗?的主要内容,如果未能解决你的问题,请参考以下文章
为什么我需要将方法强制转换为`Action`或`Func`以在值元组中使用它?