Can I use params in Action or Func delegates?
When I'm trying开发者_如何学Python to use params in an Action delegate...
private Action<string, params object[]> WriteToLogCallBack;
I received this design time error:
Invalid token 'params' in class, struct, or interface member declaration
Any help!
How about this workaround?
private Action<string, object[]> writeToLogCallBack;
public void WriteToLogCallBack(string s, params object[] args)
{
if(writeToLogCallBack!=null)
writeToLogCallBack(s,args);
}
Or you could define your own delegate type:
delegate void LogAction(string s, params object[] args);
Variadic type parameters are not possible in C#.
That's why there're many declarations for Action<...>
, Func<...>
, and Tuple<...>
, for example. It would be an interesting feature, though. C++0x has them.
You could try this. It allows for any number of arguments, and you'll get a compile time error if you pass the wrong number or type of arguments.
public delegate T ParamsAction<T>(params object[] oArgs);
public static T LogAction<T>(string s, ParamsAction<T> oCallback)
{
Log(s);
T result = oCallback();
return result;
}
Foo foo = LogAction<Foo>("Hello world.", aoArgs => GetFoo(1,"",'',1.1));
You can use params
in the actual declaration of a delegate, but not in type of one. The generic parameters to an Action are only types, not the actual arguments to be passed when invoking the delegate. params is not a type, it is a keyword.
I have done a minor extension to the above code from Bryan, to show how to wrap multiple method calls.
I am using this to wrap multiple methods that contain database calls, into a single transaction.
Thanks Bryan :-)
(You can run the following in LINQPad to test)
//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
精彩评论