Скажем, у меня есть следующие две функции:По умолчанию перегрузки неоднозначных вызовов
void Foo(IEnumerable<string> bar)
{
if(bar == null)
return;
foreach(var b in bar)
{
Console.Write(b);
}
}
и
void Foo(string bar)
{
Foo(new string[] { bar });
}
Те два неоднозначны, если я передаю null
в качестве параметра.
Есть ли способ намекнуть на компилятор, чтобы устранить перегрузку? Любой атрибут или директива или что-то еще? В этом случае я бы хотел, чтобы первая функция вызывалась. Что-то вроде:
[InCaseOfAmbiguityUseThis]
public void Foo(IEnumerable<string> bar)
Так что, если я Foo(null)
компилятор будет знать, где искать и не жалуются.
Я искал какое-то время и не нашел ничего уважения.
PS: Я знаю, что я могу использовать: Foo((IEnumerable<string>)null)
, но это то, что я пытаюсь избежать: типов в реальных функциях достаточно долго и использовать общие ограничения (так что я не могу просто наследовать тип, чтобы сделать он короче), так что он много кодирует код.
Я не против иметь 'dirty' в библиотеках (где я указываю эти функции), но не в фактическом бизнес-коде (где я называю эти функции).
Кроме того, может быть много этих, возможно, неоднозначных функций, поэтому «обходной путь, чтобы не сделать их двусмысленными» не может быть и речи (вот что я сейчас использую, но мне не нравится иметь такой шаблон код)
Редактировать
Я не ищу обходные пути (то есть, делая другие функции с различными или без параметров). Я знаю все эти способы, и, как я указал, Я уже пользуюсь этим. Просто интересно, возможно ли сделать компилятор «автоматически».
Я предпочел бы не иметь функцию без параметров (реальная функция является гораздо более многословен передавая пустой параметр, чем не проходит ни один параметр на всех):
Task<IEnumerable<TResult>> GetAsyncProjected<TResult>(
IEnumerable<Expression<Func<T, bool>>> filters,
Expression<Func<T, TResult>> projection,
IEnumerable<string> eagerLoadRelationships,
CancellationToken cancellationToken,
ServiceRefreshMode refreshMode);
Task<IEnumerable<TResult>> GetAsyncProjected<TResult>(
Expression<Func<T, bool>> filter,
Expression<Func<T, TResult>> projection,
IEnumerable<string> eagerLoadRelationships,
CancellationToken cancellationToken,
ServiceRefreshMode refreshMode);
// ... plenty of overloads for each possible parameter ...
У меня есть еще один перегрузки для каждого из них перегрузки без параметра filter
/filters
, но я бы предпочел не делать так, чтобы вызывающий абонент знал, что он пропускает null
для фильтра.
Если нет никакой возможности, то я буду искать другие пути (назвав его GetAsyncFilteredProjected()
, если он имеет параметр или что-то)
Нет, нет. Это просто двусмысленно, если вы используете нулевой литерал при вызове метода. Подумайте, почему вы так часто передаете нулевой литерал. Возможно, вам нужна безпараметрическая перегрузка. –
Другой возможной альтернативой является объявление методов как 'params string []', что позволяет вызывающему абоненту поставлять любое количество строк в строке, в том числе и ничто (с недостатком, который вы не можете передать ему «IEnumerable» без сначала выполнив '.ToArray()'). –
@JeroenMostert, который был бы действителен только в том случае, если параметр является последним параметром функции (в «реальном» случае это не так) – Jcl