What happens to C# 4 optional parameters when compiling against 3.5?
Here’s a method declaration that uses optional parameters:
public Path Copy(
Path destination,
bool overwrite = false,
bool recursive = false)
Something you may not know is that Visual Studio 2010 will let you compile this against .NET 3.5, with no error or warning.
You may be wondering (as I was) how it does that. Well, it takes the easy and rather obvious way of not trying to be too smart and just ignores the optional parameters. Well, actually optional parameters have always existed in VB.NET (and thus also in the CLR), it's just that C# has not been supporting them so far. So that code will compile to an optional parameter as they have existed for a while. For example, the overwrite parameter will have an Optional atribute and a DefaultParameterValue(false) attribute. Note that you could have added those attributes with previous versions of C#, it's just that the syntax was not that nice.
To summarize, if you target 3.5, Visual Studio will make your optional parameters usable from VB and any language that supports optional parameters. But if you are using C# 3.5 the above code is equivalent to:
public Path Copy(
Path destination,
bool overwrite,
bool recursive)
The parameters are not optional (no such thing in C# 3), and no overload gets magically created for you.
If you’re building a library that is going to have both 3.5 and 4.0 versions, and you want 3.5 users to have reasonable overloads of your methods, you’ll have to provide those yourself, which means that providing a version with optional parameters for the benefit of 4.0 users is not going to provide that much value…
Providing all of the following overloads will compile against both 3.5 and 4.0:
public Path Copy(Path destination)
public Path Copy(Path destination, bool overwrite)
public Path Copy(
Path destination,
bool overwrite = false,
bool recursive = false)
UPDATE: as several readers have pointed out, what I wrote was not quite accurate and the compiler does output an optional parameter even when targeting C# 3.5, it's just that C# 3.5 will not be able to take advantage of that extra information. I updated the post to reflect that. Thanks to all who exposed the error.