Alain
Alain

Reputation: 27220

Ambiguous method definitions, but want to maintain backwards compatibility

I have this old method signature that I want to deprecate:

[Obsolete("This method has been replaced with one that uses an arguments object")]
public static T PollUntilReady<T>(
    Func<T> functionThatMight503,
    double minPollInterval = 0d,
    double maxPollInterval = double.MaxValue,
    double maxPollTotalTime = double.MaxValue);

I want to replace this with a more forward-looking variation that uses a parameters argument for the various options that may be added in the future:

public static T PollUntilReady<T>(
    Func<T> functionThatMight503,
    PollingOptions pollingOptions = null);

The problem is if no options are specified, the compiler complains that the method call is ambiguous. ("The call is ambiguous between the following methods...")

Is there any way I can resolve this without breaking backwards compatibility, renaming the new function, or compromising the new method's flexibility (optional options object)?

Upvotes: 3

Views: 212

Answers (2)

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239734

You can implement it as two functions instead:

public static T PollUntilReady<T>(Func<T> functionThatMight503)
{
    return PollUntilReady(functionThatMight503, null);
}

public static T PollUntilReady<T>(
    Func<T> functionThatMight503,
    PollingOptions pollingOptions)
{
    throw new NotSupportedException(); //Whatever
}

When called with only a single argument, the compiler can now resolve the ambiguity since it has a function to choose from that doesn't require any defaults.

This does mean that the default value for pollingOptions is now baked into your code rather than the calling code, which means that if you choose to change the default value later, older code will receive the new default even without recompilation.


This avoids ambiguity thanks to the overload resolution rule:

Otherwise if all parameters of MP have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in MQ then MP is better than MQ

from section 7.5.3.2 of the C# language spec.

Upvotes: 4

Tom B.
Tom B.

Reputation: 2962

The only way I see is that you have to remove the possibility to have an ambiguous method definition. Instead of setting pollingOptions = null by default, you'll always have to pass something.

So change your method signature to this:

public static T PollUntilReady<T>(
    Func<T> functionThatMight503,
    PollingOptions pollingOptions);

To use your new method defintion you have to pass pollingoptions or null.

The only way according to me even if you asked not to compromising the optional args.

Upvotes: 1

Related Questions