I still don't think a large portion of .NET developers know that adding optional parameters is a (binary) breaking change.
Requests on details here - fair enough!

Let's say you have a method in a library:
Get(string foo)

Caller: Get("test")

You add an optional param, let's say:
Get(string foo, int bar = 0)

("Type is not important here")

Without a re-compile, that's a missing method exception.
Why? Because the method was Get(string), now the method is Get(string, int).

Optional params, importantly, are baked in *AT THE CALLER*. So if your code is calling:
Get("test")
...what that's actually compiling to is:
Get("test", 0)
(whatever the default was at compile time)
This also means changing the default value from say 0 to 2 in this example, is a breaking change. People compiling against you when it was 0 have 0. People who compiled at 2 have 2. Upgrading the library reference will not change the constant they compiled *at the call site*.
In short: adding an optional param to a method breaks binary compatibility because the signature that callers are looking is no longer there...they're looking for the old one, with one less parameter.

I hate to see a new contributor bitten by this, but yeah: that's how it works.
Also note: breaks via transitive refs are an extra layer of fun here you may not even realize. This simple friendly example assumes people respecting SemVer...if they don't, it's even worse :) https://twitter.com/Nick_Craver/status/1387190231179403277
You can follow @Nick_Craver.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: