I am aware that adding an optional parameter in a library method is a breaking change,
void Foo(int x) // OLD
void Foo(int x, int y = 5) // NEW
because in the compiled code the new version is seen as Foo(int, int). Every call of Foo(0) (source code) is translated to Foo(0, 5) (compiled code) by the compiler. Thus, an old client, using a compiled call of Foo(0) would not find a suitable method.
What about the other direction?
void Foo(int x, int y = 5) { ... } // OLD
void Foo(int x) { Foo(x, 5); } // NEW
void Foo(int x, int y) { ... } // NEW
Foo(0) (source code) would still compile, and Foo(0, 5) (compiled code) would still find a suitable overload, so, theoretically, this should work.
Does it work in practice, i.e., is this scenario “officially supported” by the .NET runtime and the C#/VB compilers? Or are calls to methods with optional parameters somehow “marked”, causing them to fail when the optional parameters are replaced by overloads?
EDIT: To clarify, I’m asking about binary compatibility: Is it possible to replace library.dll (old) with library.dll (new) without recompiling projectUsingLibrary.exe?
I thought that was a good question, so here goes my take.
Using a quick client that does this:
When using optional parameter the client IL looks like:
and when using overloads it looks like:
So, if you changed the implementation from optional to overloads, but left the client as it was originally, it would be effectively adding the default parameter for you, and always calling the the function that has two arguments, which may or may not be the desired behaviour.