36

For instance, the System.IO.Path.Combine method in .NET has the following overloads:

Combine(params String[])
Combine(String, String)
Combine(String, String, String)
Combine(String, String, String, String)

What is the point of the last three?

The first one would cover them all, as if you look closely, it uses the params keyword. The argument of backwards compatibility would only cover the Combine(String, String) variant, as it was the only version until .NET 4.

Peter Mortensen
  • 1,050
  • 2
  • 12
  • 14
Alex
  • 470
  • 3
  • 7

2 Answers2

56

The main reason is for performance. The "unlimited arguments" syntactical sugar is actually an array of Strings. If you are only passing one string, why create an array with only one string? Especially if ~90% of the invocations of this method will be with 3 or fewer arguments, there is no need for the heavier weight array object. It's a little lighter in memory and takes a little less processing time because you don't need a loop in order to define the method. If you have three strings, you just code for three strings.

Greg Burghardt
  • 34,276
  • 8
  • 63
  • 114
  • Another thing to note is that passing `Combine` with zero or one path segments does not even make sense, yet the `params` version allows you to do this. – Matthew May 04 '15 at 18:31
  • How about readability? – Brandon May 04 '15 at 19:00
  • 4
    The reason for the numbers of _overloads_ accepting different numbers of arguments is not for readability. It is for performance because of the overhead incurred by generating an array of strings, and then processing them. The reason for accepting `params string[]` is for readability. – Greg Burghardt May 04 '15 at 19:01
  • 4
    Performance is indeed the reason, and I believe it's specifically for when a function is expected to be *called from inside loops*. As Brad Abrams's annotation on p.27 of *The C# Programming Language, Third Edition* says: "[T]he C# model does create an extra object allocation (the containing array) implicitly on each call. This is rarely a problem, but in inner-loop type scenarios where it could get inefficient, we suggest providing overloads for the mainstream cases and using the `params` overload for only the edge cases. An example is the `StringBuilder.AppendFormat()` family of overloads." – Eliah Kagan May 05 '15 at 01:38
  • If you look at the code of Path.cs (https://github.com/mono/mono/blob/master/mcs/class/corlib/System.IO/Path.cs) in Mono, you can see the Combine with 3 and 4 parameters are just creating an array and passing it to the method accepting string[] as argument. This does not have anything to do with performance but the readability – Low Flying Pelican May 05 '15 at 06:56
  • 3
    @LowFlyingPelican Mono and the .NET Framework are not the same. If you look at the [.NET Framework version](http://referencesource.microsoft.com/#mscorlib/system/io/path.cs,2d7263f86a526264), it's actually quite a different solution. – Alex May 05 '15 at 07:51
  • 3
    @LowFlyingPelican: The .NET framework's reason *is* performance. Mono's reason for implementing that method was API compatibility with .NET. Mono's reason for implementing that method in that way was implementation simplicity (on account of them having considerably less resources than Microsoft). – jhominal May 05 '15 at 08:30
4

Syntactic sugar.

When manipulating file paths, it is extremely common to have a small number of fixed values. In these cases, it is more convenient to use them directly rather than having to package them into an array.

Gort the Robot
  • 14,733
  • 4
  • 51
  • 60
  • 3
    With params, you are sugering it already. https://msdn.microsoft.com/en-us/library/w5zay9db.aspx No need of an array. – Thomas Junk May 04 '15 at 15:58
  • 3
    In C#, you have a point, @Thomas. However, .NET also supports other languages without `params`. – Karl Bielefeldt May 04 '15 at 16:05
  • @ThomasJunk That link is dead for me, unfortunately, but I am sure you are right as my C# is mediocre. I just have seen many libraries with many languages that do that just to allow cleaner code. – Gort the Robot May 04 '15 at 20:08