54

When I'm trying 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!

1
  • 1
    params is not a type, i.e you can use ref in type definition? Commented Oct 30, 2010 at 17:09

5 Answers 5

51

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); 
Sign up to request clarification or add additional context in comments.

1 Comment

How do you call this with a lambda?
12

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.

1 Comment

Not sure how well it would work with generics (as opposed to templates).
8

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)); 

4 Comments

This is a really nice way of doing it... Nice work sir
Awesome piece of code here Bryan. I have added below a minor extension to the above code 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 :-)
Was this supposed to return result instead of T?
what's the point of it if you cannot do LogAction<Foo>("Hello world.", (p1,p2,p3) => GetFoo(p1,p2,p3));??? minusing....
3

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.

Comments

3

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 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.