重载决策 (Visual Basic)
当 Visual Basic 编译器遇到对在多个重载版本中定义的过程的调用时,编译器必须决定调用哪一个重载。 为此,它执行以下步骤:
**辅助功能。**它消除具有防止调用代码调用的访问级别的任何重载。
**参数的数量。**它消除所定义的参数数量与调用中提供的数量不同的任何重载。
**参数数据类型。**编译器赋予实例方法的优先级高于扩展方法。 如果找到任何只需要经过扩大转换就能匹配过程调用的实例方法,则忽略所有扩展方法,并且编译器仅使用实例方法候选继续进行编译。 如果未找到这样的实例方法,则编译器将使用实例方法和扩展方法继续进行编译。
在此步骤中,它消除调用实参的数据类型无法转换成重载中定义的形参类型的任何重载。
**收缩转换。**它消除需要从调用参数类型到定义的参数类型进行双字节到单字节转换的任何重载。 无论类型检查开关 (Option Strict 语句) 是 On 还是 Off 都是如此。
**最小扩大。**编译器成对考虑其余的重载。 对于每一对重载,它比较已定义参数的数据类型。 如果其中一个重载中的类型全部扩展为另一个中的相应类型,编译器消除后者。 即,它保留要求最少量扩展的重载。
**单个候选项。**它继续成对考虑重载,直到只剩下一个重载为止,并解析对该重载的调用。 如果编译器不能将重载减少到一个候选项,将产生错误。
下图显示决定调用哪个重载版本的进程。
在重载版本中决策
下面的示例阐释了此重载决策过程。
Overloads Sub z(ByVal x As Byte, ByVal y As Double)
End Sub
Overloads Sub z(ByVal x As Short, ByVal y As Single)
End Sub
Overloads Sub z(ByVal x As Integer, ByVal y As Single)
End Sub
Dim r, s As Short
Call z(r, s)
Dim p As Byte, q As Short
' The following statement causes an overload resolution error.
Call z(p, q)
在第一个调用中,编译器将消除第一个重载,因为第一个参数 (Argument) 的类型 (Short) 将收缩为相应参数 (Parameter) 的类型 (Byte)。 接着,编译器消除第三个重载,因为第二个重载中的每个参数 (Argument) 类型(Short 和 Single)都将扩大为第三个重载中的相应类型(Integer 和 Single)。 第二个重载需要的扩大量较少,因此编译器将用它进行调用。
在第二个调用中,编译器不能根据收缩消除任何重载。 与第一个调用中的原因相同,编译器将消除第三个重载,因为它可以用参数 (Argument) 类型的最少扩大量调用第二个重载。 然而,编译器无法在第一个和第二个重载之间解析。 每个重载都有一个已定义的参数类型,该类型将扩大到另一个重载中的相应类型(从 Byte 扩大为 Short,但从 Single 扩大为 Double)。 编译器因此生成重载决策错误。
重载的 Optional 和 ParamArray 参数
如果一个过程的两个重载具有相同的签名,只是最后一个参数在一个重载中声明为 Optional (Visual Basic) 而在另一个重载中声明为 ParamArray (Visual Basic),则编译器将按照以下方式解析调用:
如果该调用提供的最后一个参数为 |
编译器将把该调用解析到将最后一个参数声明为以下类型的重载 |
无值(省略该参数) |
Optional |
一个值 |
Optional |
逗号分隔的列表中的两个或多个值 |
ParamArray |
任何长度的数组(包括空数组) |
ParamArray |
请参见
任务
如何:重载参数数量不确定的过程 (Visual Basic)