方法定义不明确,但希望保持向后兼容性

Ambiguous method definitions, but want to maintain backwards compatibility

我想弃用这个旧方法签名:

[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);

我想用一个更具前瞻性的变体来替换它,该变体使用参数参数来表示将来可能添加的各种选项:

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

问题是如果没有指定选项,编译器会抱怨方法调用不明确。 ("The call is ambiguous between the following methods...")

有什么方法可以在不破坏向后兼容性、重命名新函数或损害新方法的灵活性(可选选项对象)的情况下解决这个问题?

我看到的唯一方法是您必须消除方法定义不明确的可能性。而不是设置 pollingOptions = null 默认情况下,你总是必须传递一些东西。

因此将您的方法签名更改为:

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

要使用您的新方法定义,您必须传递 pollingoptions 或 null。

我认为这是唯一的方法,即使您要求不要妥协可选参数。

您可以将其实现为两个函数:

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
}

当只用一个参数调用时,编译器现在可以解决歧义,因为它有一个不需要任何默认值的函数可供选择。

这确实意味着 pollingOptions 的默认值现在已嵌入到您的代码中,而不是调用代码中,这意味着如果您选择稍后更改默认值,旧代码将接收新的默认值即使没有重新编译。


由于重载解析规则,这避免了歧义:

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

来自 C# 语言规范的第 7.5.3.2 节