模棱两可的方法调用C#

时间:2018-12-06 11:34:11

标签: c#

谁能解释为什么使用这些方法?

public IEnumerable<Role> GetRoles(Func<Role, bool> predicate = null)
public IEnumerable<Role> GetRoles(params User[] users)

如果我调用GetRoles(null),则不会编译,因为方法调用是模棱两可的,这是正确的,但是,如果我调用GetRoles(),这是合法的,并选择了public IEnumerable<Role> GetRoles(Func<Role, bool> predicate = null)方法。为什么这还不明确?

2 个答案:

答案 0 :(得分:3)

GetRoles()的调用不是模棱两可的,因为在没有参数的情况下,GetRoles(params User[] users)仅以其展开形式*适用,并且C# language specification的§12.6.4.3指定在如果是平局,则适用某些打破平局规则,第二个规则是:

  

否则,如果M P 以其正常形式适用且M Q   具有params数组,并且仅以扩展形式适用,则M P 优于M Q

因此,GetRoles(Func<Role, bool> predicate = null)GetRoles(params User[] users)更好。

但是,在调用GetRoles(null)时,params User[] users既适用于展开形式,也适用于非展开形式,在这种情况下,适用于the expanded form is discarded。这使您拥有:

GetRoles(Func<Role, bool> predicate = null)
GetRoles(User[] users)

,现在无法为GetRoles(null)选择更好的匹配。您必须give a type to that null,以便过载解决方案可以据此选择最佳候选。


  

*扩展形式是通过用零个或多个参数数组元素类型的值参数替换函数成员声明中的参数数组,从而使参数列表{{1}中的参数数量}与参数总数匹配。
  C# Language specification,§12.6.4.2

答案 1 :(得分:0)

这是因为两个参数都可以为空,因此这两种方法都可以将null值作为输入,并且无法区分它们。

编译器不知道nullFunc<Role, bool>还是User[] users,并且没有足够的信息来对要调用的方法做任何假设。

您可以按如下方式向编译器提供更多信息:

Func<Role, bool> predicate = null;
GetRoles(predicate); // calls --> GetRoles(Func<Role, bool> predicate = null)

以及其他方法:

User[] users = null;
GetRoles(users); // calls GetRoles(params User[] users)