我有这个旧方法签名,我想弃用:
[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;)
有什么方法可以解决这个问题,而不会破坏向后兼容性,重命名新功能,或者破坏新方法的灵活性(可选选项对象)?
答案 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。