Having lived in both overload world and optional parameter world, I have found optional parameters to be infinitely more useful, especially when there are SEVERAL optional parameters that you may or may not want. Most of the time when I see the overload style, we have several:
public void A() { A(1); }
public void A(a) { A(a, 2); }
public void A(a, b) { A(a, b, c); }
public void A(a, b, c) { /* do something */ }
Or, worse,
public void A() { A(1, 2, 3); }
public void A(a) { A(a, 2, 3); }
public void A(a, b) { A(a, b, 3); }
public void A(a, b, c) { /* do something */ }
It wastes several lines and could be much more simply expressed, to the developer as:
public void A(a = 1, b = 2, c = 3) { /* do something */ }
Regarding the issue you have, I can certainly see that as an actual issue and it should probably be dealt with; though, the CLR developers probably had to decide between two opposing and frustrating viewpoints: "What if they want the old default? After all, they did compile against it, knowing that that's what we set it to default"; and, "Maybe they just want the computer to figure out what's best for them..." As a library designer, you'll now have to consider the possibility that they're using the old version of your library. Realistically, they most likely will compile their program again instead of in-place replacing your dll. It's safer that way.
All of that said, when I usually use optional parameters, I generally set them to null. You cannot set them to, for example, a new instance of an object, they have to be static values; so, if someone uses a default parameter, my code sees: "oh, it's null. Now I'll use my default parameter that I set internally, because it came from a configuration file and I couldn't set that as a default parameter anyway given their constraints", and I don't have the problem you mention at all.
Example:
public void A(a = null, b = null, c = null) {
a = a ?? new AParam();
b = b ?? SomePropertyFromAConfigFile;
c = c ?? DBNull.Value;
/* do something */
}
The ?? syntax makes this practically the recommended route, I think. (a ?? b is C# shorthand for (a != null? a : b) ). I'm happy, the people using my library are happy, and the issue that you describe doesn't exist in my code because of this. Of course it does make it a bit awkward for some kinds of primitives, for example; but, if they don't want to provide a parameter to my library, that parameter being provided as 'null' seems the most accurate way for my library to receive it anyway.