简体   繁体   English

模糊方法调用c#

[英]Ambiguous method calls c#

Can anyone explain why for these methods: 任何人都可以解释为什么这些方法:

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

If I call GetRoles(null) it won't compile because the method call is ambiguous, and rightly so, but if I call GetRoles() this is legal and selects the public IEnumerable<Role> GetRoles(Func<Role, bool> predicate = null) method. 如果我调用GetRoles(null)它将无法编译,因为方法调用是不明确的,这是正确的,但如果我调用GetRoles()这是合法的并选择public IEnumerable<Role> GetRoles(Func<Role, bool> predicate = null)方法。 Why is this not also ambiguous? 为什么这也不模糊?

A call to GetRoles() is not ambiguous because in the absence of parameters, GetRoles(params User[] users) only applies in its expanded form*, and §12.6.4.3 of the C# language specification specifies that in a case of a tie certain tie-breaking rules apply, the second one being: GetRoles()调用不明确,因为在没有参数的情况下, GetRoles(params User[] users)仅适用于其扩展形式*,而C#语言规范的 §12.6.4.3指定在绑定的情况下某些打破平局规则适用,第二个是:

Otherwise, if M P is applicable in its normal form and M Q has a params array and is applicable only in its expanded form, then M P is better than M Q . 否则,如果M P以其正常形式适用且M Q具有params阵列并且仅适用于其扩展形式,则M P优于M Q.

Thus GetRoles(Func<Role, bool> predicate = null) is ruled to be better than GetRoles(params User[] users) . 因此, GetRoles(Func<Role, bool> predicate = null)被裁定为优于GetRoles(params User[] users)

In a call to GetRoles(null) , however, the params User[] users applies both in expanded and in non-expanded form, in which case the expanded form is discarded . 但是,在调用GetRoles(null)时, params User[] users应用展开形式和非展开形式,在这种情况下,展开的表单将被丢弃 This leaves you with: 这让你:

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

and now there is no way to choose a better match for GetRoles(null) . 现在没有办法为GetRoles(null)选择更好的匹配。 You have to give a type to that null so that overload resolution can pick the best candidate based on that. 您必须为该null指定一个类型,以便重载决策可以根据该选择选择最佳候选者。


* The expanded form is constructed by replacing the parameter array in the function member declaration with zero or more value parameters of the element type of the parameter array such that the number of arguments in the argument list A matches the total number of parameters. *通过使用参数数组的元素类型的零个或多个值参数替换函数成员声明中的参数数组来构造展开形式,使得参数列表A中的参数数量与参数的总数相匹配。
C# Language specification , §12.6.4.2 C#语言规范 ,§12.6.4.2

This is because both parameters are nullable and hence both methods could take a null value as input and there's no way to distinguish them. 这是因为两个参数都是可空的,因此两个方法都可以将null值作为输入,并且无法区分它们。

The compiler doesn't know if null should be Func<Role, bool> or User[] users and doesn't have enough information to make any assumptions on the method to invoke. 编译器不知道null是否应该是Func<Role, bool>User[] users ,并且没有足够的信息来对要调用的方法做出任何假设。

You can provide more information to the compiler as follows: 您可以按如下方式向编译器提供更多信息:

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

and for the other method: 而对于另一种方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM