69

How can i create a method that has optional parameters and params together?

static void Main(string[] args)
{

    TestOptional("A",C: "D", "E");//this will not build
    TestOptional("A",C: "D"); //this does work , but i can only set 1 param
    Console.ReadLine();
}

public static void TestOptional(string A, int B = 0, params string[] C)
{
    Console.WriteLine(A);
    Console.WriteLine(B);
    Console.WriteLine(C.Count());
}   
svick
  • 236,525
  • 50
  • 385
  • 514
MichaelD
  • 8,377
  • 10
  • 42
  • 47

3 Answers3

48

Your only option right now is to overload the TestOptional (as you had to do before C# 4). Not preferred, but it cleans up the code at the point of usage.

public static void TestOptional(string A, params string[] C)
{
    TestOptional(A, 0, C);
}

public static void TestOptional(string A, int B, params string[] C)
{
    Console.WriteLine(A);
    Console.WriteLine(B);
    Console.WriteLine(C.Count());
}
CodeMonkeyKing
  • 4,556
  • 1
  • 32
  • 34
  • 3
    Yep, this is the only way to accomplish what the OP is asking that I know of. I don't think it's necessarily bad though. Just creates a little more code but it's simple enough to not be confusing. – Jeff LaFay Feb 09 '11 at 20:29
  • 12
    Also, this doesn't work for Method Caller Information Attributes, such as `[CallerMemberName]`. – Caleb Jares Jun 07 '13 at 03:49
  • 1
    It is possible, see my answer below – katbyte Dec 18 '13 at 23:23
  • @CalebJares - `katbyte` is right, it does work if you use named arguments: https://stackoverflow.com/questions/9784630/function-with-variable-number-of-arguments#71750032 – SharpC Apr 05 '22 at 10:21
17

Try

TestOptional("A", C: new []{ "D", "E"});
Mahesh Velaga
  • 21,633
  • 5
  • 37
  • 59
  • that works well for the example. but when i would need a signature like this, i am obligated to specify the type. public static void TestOptional(T A, int B = 0, params Action[] C) – MichaelD Oct 16 '10 at 13:15
  • @MichaelD so you dont like write similar to: Action test = x => Console.WriteLine(x); Action test2 = y => Console.WriteLine(y); TestOptional("A", C: new [] { test, test2 }); Am I understand correctly or what do you mean? – Nick Martyshchenko Oct 16 '10 at 18:03
  • 1
    Using your method and the signature i previously commented. The parser needs the type 'new Action[]' ant not just 'new[]'. This results in much 'code-noise' when dealing with expressions of generic types and so on. Example on the simpler signature: TestOptional("A",C: new Action[]{ d=>d.ToString(),d=>d.ToString()}); – MichaelD Oct 16 '10 at 18:23
16

This worked for me:

    static void Main(string[] args) {

        TestOptional("A");
        TestOptional("A", 1);
        TestOptional("A", 2, "C1", "C2", "C3"); 

        TestOptional("A", B:2); 
        TestOptional("A", C: new [] {"C1", "C2", "C3"}); 

        Console.ReadLine();
    }

    public static void TestOptional(string A, int B = 0, params string[] C) {
        Console.WriteLine("A: " + A);
        Console.WriteLine("B: " + B);
        Console.WriteLine("C: " + C.Length);
        Console.WriteLine();
    }
katbyte
  • 2,665
  • 2
  • 28
  • 19
  • 2
    This doesn't match with the signature the OP has. The 'B' is now a string which can be null. In addition this answer changed 'C' to an object. This is an answer to a different question. Types matter. – CodeMonkeyKing Dec 20 '13 at 00:18
  • 1
    The question was "How can i create a method that has optional parameters and params together?" and my answer showed how to do so. However yes i used different types because I was trying to accomplish something different. Easy enough to change the types to match. – katbyte Dec 20 '13 at 01:11
  • 2
    Yes this will work. It adds the clutter of the new[] { }, which is not exactly how you would want to write this given that most of the time you never have to do that with a params, in fact it is unexpected to have to do that. The OP's question illustrates that the compiler cannot infer a named 'params' parameter using the params syntax at the calling site. – CodeMonkeyKing Dec 20 '13 at 01:26