模糊的方法定义,但希望保持向后兼容性

时间:2016-08-17 13:42:42

标签: c# .net-4.5 overloading 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);

问题是如果没有指定选项,编译器会抱怨方法调用不明确。 (&#34;以下方法之间的呼叫不明确......&#34;)

有什么方法可以解决这个问题,而不会破坏向后兼容性,重命名新功能,或者破坏新方法的灵活性(可选选项对象)?

2 个答案:

答案 0 :(得分:4)

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

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的默认值现在已经烘焙到您的代码而不是调用代码中,这意味着如果您选择稍后更改默认值,即使没有,旧代码也会收到新的默认值重新编译。

由于重载决策规则,这可以避免歧义:

  

否则,如果M P 的所有参数都有相应的参数,而默认参数需要替换M Q 中的至少一个可选参数,则M P 优于M Q

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

答案 1 :(得分:1)

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

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

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

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

根据我的唯一方法,即使你要求不要破坏可选的args。