2

假设我有以下两个功能:

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)但这就是我要避免的:实际函数中的类型很长并且使用通用约束(所以我不能只继承类型以使其更短),所以它很脏代码很多。

我不介意它在库中“脏”(我在其中指定这些函数),但不在实际业务代码中(我在其中调用这些函数)。

此外,可能有很多这些可能模棱两可的函数,所以“不让它们模棱两可的解决方法”是不可能的(这就是我现在正在使用的,但我不喜欢这样的样板代码)

编辑

我不是在寻找解决方法(即,使用不同的参数或没有参数的其他函数)。我知道所有这些方式,并且正如我所指定的,我已经在使用. 只是想知道是否真的可以让编译器“自动”消除歧义。

我不希望有一个无参数函数(真正的函数传递一个空参数比不传递任何参数要详细得多):

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()有参数什么的就调用)

4

1 回答 1

3

没有办法像这样在 C# 中自定义重载。选择方法重载有严格的规则。

但是,如果你想提供一个不带参数的方法版本,你可以创建一个新的重载而不是传递null

void Foo()
{
    Foo((string)null);
}

作为奖励,它会更具可读性。

此外,如果您无法修改原始类并且它们不提供您需要的重载,则可以使用扩展方法。这将保持业务逻辑干净。

于 2014-10-22T16:25:17.523 回答