2016-08-17 9 views
3

У меня есть эта старый метод подпись, который я хочу принизить:определение Неоднозначного метода, но хочет сохранить обратную совместимость

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

проблема, если не указаны опции, компилятор жалуется, что вызов метода неоднозначен. («Вызов неоднозначен между следующими методами ...»)

Есть ли способ разрешить это, не нарушая совместимость, переименование новой функции или нарушение гибкости нового метода (объект дополнительных опций)?

+1

Передайте 'null' как параметр' pollingOptions'. – DavidG

+2

Самый простой способ, вероятно, состоит в том, чтобы _not_ иметь 'pollingOptions' в качестве необязательного параметра. Вместо этого создайте объект «PollingOptions.Default» или что-то подобное, поэтому его все равно легко вызвать. – MAV

ответ

3

Вы можете реализовать его как две функции вместо:

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

из раздела 7.5.3.2 спецификации языка C#.

+0

Не знаю, почему я об этом не думал. Вы мой спаситель :) – Alain

+0

Будет ли первый вариант не отображаться как неоднозначный по отношению к оригиналу? (Я собираюсь протестировать, просто не знаю, почему это не так) – Alain

+1

@Alain - обновляется с цитатой из спецификации.Кроме того, я действительно поместил все эти определения в свою программу с нуля и убедился, что различные тестовые примеры скомпилированы с использованием этих новых методов. –

1

Единственный способ, который я вижу, - это удалить возможность определения двусмысленного метода. Вместо того, чтобы устанавливать pollingOptions = null по умолчанию, вам всегда нужно что-то передать.

Так изменить метод подписи к этому:

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

Чтобы использовать новый метод дефиниция вы должны пройти pollingoptions или нуль.

Единственный способ по мне, даже если вы попросили не компрометировать необязательные аргументы.

 Смежные вопросы

  • Нет связанных вопросов^_^