2

I have this test code:

    void func1(string a, params string[] p)
    {
        func1(a, true, p);
    }

    void func1(string a, bool b, params string[] p)
    {
        //...
    }

    void func2(string a, bool b = true, params string[] p)
    {
        //...
    }

    void exec()
    {
        func1("a", "p1", "p2");
        func2("a", "p1", "p2");
    }

Is func1 and func2 equals?

There are no errors when I create the func2, but, when I try to use the func2 like in exec (using the optional value), the compiler show an error This function has some invalid arguments.

I think that func1 and func2 are equal for someone that will consume this function like an API.

What is wrong with this code? Can I use this approach for functions that have optional and params values?

Bruno Croys Felthes
  • 1,183
  • 8
  • 27
  • 1
    I like the question... But please think twice before actually writing such code - you already have trouble to reason what and how will be called while you just wrote the code. Imagine when someone else (or even you 2 month later) will try to use it... You really don't want comment in your coding guidelines "Always specify all arguments to XXXX function because otherwise you'll get strange errors/unpredictable behavior ..." – Alexei Levenkov Feb 08 '13 at 17:14

1 Answers1

10

Normally optional parameters have to come at the end of a method declaration - a parameter array (such as p here) is the only exception to that. But when it comes to using the arguments, the compiler will assume that all positional arguments are in the same order as the method declaration... so you get into trouble if you want to use the optionality and the parameter array side. This should be okay:

func2("a", p: new[] { "p1", "p2" })

but personally I'd just steer clear of mixing parameter arrays and optional parameters. It's clearly confusing.

I believe the relevant section of the C# 5 specification is 7.5.1.1, which includes:

A positional argument of a function member with a parameter array invoked in its expanded form, where no fixed parameter occurs at the same position in the parameter list, corresponds to an element of the parameter array.

See also section 7.5.3.1. It's all pretty complicated...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • OK, but about my first question, `func1` is equal to `func2`? I can't see the difference. – Bruno Croys Felthes Feb 08 '13 at 17:26
  • @BrunoCroysFelthes: You'd have to define what you mean by "equal" first. They're clearly not "equal" in that `func1` has two overloads whereas `func2` only has one... – Jon Skeet Feb 08 '13 at 17:40