3

I've come across a library method with three parameters, all with default values:

virtual M(bool b1 = false, string s1 = null, bool b2 = true) 

Method M shouldn't have parameter s1, so I want to remove it, but I don't want to make a breaking change in the DLL. Clients can obviously ignore s1, but I don't want to leave it there because M can be overridden and parameter s1 is misleading. So here was my attempt:

virtual M(bool b1 = false, bool b2 = true) [Obsolete] virtual M(bool b1, string s1, bool b2 = true) 

I figured that since optional parameters are compiled into the call site, existing clients would carry on calling the method with three parameters, whereas new or recompiled clients not using s1 would link to the method with two parameters.

Each call to M resolves okay, except this one:

M(b2: false); 

The compiler reports that the call is ambiguous between "M(bool, bool)" and "M(bool, string, bool)".

Oddly, in the parameter info (Ctrl+Shift+Space), Visual Studio is still showing the default values on the method with three parameters (despite cleaning and rebuilding, restarting VS, unloading and reloading projects).

Obviously I can fix this by calling the new M something different, but I'm curious as to why it's not linking. Should it (and something's just out of step, as the out-of-date parameter info suggests), or does the compiler have a genuine issue with this?

EDIT

Like @p.s.w.g and as per @JonSkeet's suggestion, I can't reproduce this in fresh code, so I guess the question becomes: is there anything else I can try other than rebuilding, restarting, reloading to force VS to relink this?

10
  • 2
    I'm not able to reproduce the issue using just the methods in your second snippet. It compiles just fine for me. But yeah, I'd recommend changing the name if you can anyway. It's usually easier to communicate to clients "Method M is obsolete, use N now" rather than, "Use the overload of M that only accepts two bools". Commented Jul 11, 2014 at 15:54
  • I don't quite understand the question. How could that call not be ambiguous? Commented Jul 11, 2014 at 15:55
  • 4
    @Jon: The second method (in the new case) has two required parameters, which aren't being specified. Commented Jul 11, 2014 at 15:57
  • 1
    Yes, it does sound like it's out of sync. Can you reproduce this with "fresh" code? Commented Jul 11, 2014 at 15:57
  • 1
    are you referencing the dll directly rather than a project link? Commented Jul 11, 2014 at 16:12

1 Answer 1

1

Well this is embarrassing and interesting in equal measures (okay - maybe slightly more embarrassing than interesting).

The compiler was correct (as it almost always is!). I had assumed that the compiler error was referring to the two M methods I outlined in the question, but the client code with the error was also overriding the original M with three parameters, and still providing the defaults to all three parameters.

I only discovered "the third M" when I actually added the [Obsolete] (sorry - I'd only posted it for illustration - didn't think that would be relevant) and got a warning about overriding an obsolete method.

I think this probably supports @p.s.w.g's comment!

Sign up to request clarification or add additional context in comments.

2 Comments

Overriding a method while changing which parameters are optional is really confusing, and this seems to be what happens in your case (because the virtual base method changed). Another thing that is confusing is if the override renames the parameters, the worst case being if b1 is renamed to b2 in the override.
@JeppeStigNielsen: I agree with you. I thought this might be a good way to keep the interface clean by removing the unwanted extra parameter, but the fact it's also virtual makes this too confusing. I'm looking for another solution!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.