C# 4.0, optional parameters and params do not work together

21,966

Solution 1

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

Solution 2

Try

TestOptional("A", C: new []{ "D", "E"});

Solution 3

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();
    }
Share:
21,966
MichaelD
Author by

MichaelD

Updated on July 05, 2022

Comments

  • MichaelD
    MichaelD almost 2 years

    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());
    }   
    
  • MichaelD
    MichaelD over 13 years
    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>(T A, int B = 0, params Action<T>[] C)
  • Nick Martyshchenko
    Nick Martyshchenko over 13 years
    @MichaelD so you dont like write similar to: Action<string> test = x => Console.WriteLine(x); Action<string> test2 = y => Console.WriteLine(y); TestOptional("A", C: new [] { test, test2 }); Am I understand correctly or what do you mean?
  • MichaelD
    MichaelD over 13 years
    Using your method and the signature i previously commented. The parser needs the type 'new Action<string>[]' 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<string>[]{ d=>d.ToString(),d=>d.ToString()});
  • Jeff LaFay
    Jeff LaFay over 13 years
    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.
  • Caleb Jares
    Caleb Jares almost 11 years
    Also, this doesn't work for Method Caller Information Attributes, such as [CallerMemberName].
  • katbyte
    katbyte over 10 years
    It is possible, see my answer below
  • CodeMonkeyKing
    CodeMonkeyKing over 10 years
    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.
  • katbyte
    katbyte over 10 years
    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.
  • CodeMonkeyKing
    CodeMonkeyKing over 10 years
    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.
  • SharpC
    SharpC about 2 years
    @CalebJares - katbyte is right, it does work if you use named arguments: stackoverflow.com/questions/9784630/…