培训
重载解析 (Visual Basic)
当一个过程在多个重载版本中定义时,Visual Basic 编译器必须决定调用哪个重载。 它通过执行以下步骤来决定:
- 可及性。 它消除了具有访问级别的任何重载,使调用代码无法调用它。
- 参数数。 它消除了定义的参数数量与调用中提供的参数数量不同的任何重载。
- 参数数据类型。 编译器提供实例方法优先于扩展方法。 如果发现任何实例方法只需要扩大转换才能与过程调用匹配,则会删除所有扩展方法。 编译器仅继续考虑实例方法候选项。 如果未找到此类实例方法,它将继续使用实例和扩展方法。 在此步骤中,它消除了任何无法将调用参数的数据类型转换为重载中定义的参数类型的重载。
- 收缩转换。 它消除了任何需要从调用参数类型到已定义参数类型的收缩转换的重载。 无论类型检查开关 (Option Strict Statement) 是
On
还是Off
,都会执行此步骤。 - 最少扩大。 编译器逐对考虑剩余的重载。 对于每个对,它将比较定义的参数的数据类型。 如果其中一个重载中的类型都扩大到另一个重载中的相应类型,编译器将消除后者。 即,它会保留需要最少扩大量的重载。
- 重载解析优先级。 编译器删除任何重载,该重载的 OverloadResolutionPriorityAttribute 低于任何候选重载的最高值。 不带此属性的任何重载都分配默认值为零。
- 单个候选人。 它继续考虑成对重载,直到只剩一个重载,并解析对该重载的调用。 如果编译器无法将重载减少到单个候选项,则会生成错误。
下图显示了确定要调用的一组重载版本的过程。
重载解析过程的
以下示例演示了此重载解析过程。
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)
在第一次调用中,编译器将消除第一个重载,因为第一个参数(Short
)的类型缩小到相应参数的类型(Byte
)。 然后,它消除了第三个重载,因为第二个重载(Short
和 Single
)中的每个参数类型都扩大到第三个重载(Integer
和 Single
)中的相应类型。 第二个重载需要较少的扩大,因此编译器使用它进行调用。
第二次调用中,编译器无法基于缩小来消除任何重载。 它消除第三个重载的原因与第一次调用中的原因相同,因为它可以调用第二个重载,参数类型的扩大较少。 编译器无法区分第一个和第二个重载。 每个都有一个定义的参数类型,该类型可以扩展到另一个对应的类型(Byte
到 Short
,但 Single
到 Double
)。 因此,编译器将生成重载解析错误。
如果过程的两个重载具有相同的签名,则除了最后一个参数在一个重载中声明为 Optional,在另一个重载中声明为 ParamArray 外,编译器将解析对该过程的调用,如下所示:
如果调用提供最后一个参数为 | 编译器解析对声明最后一个参数为以下形式的重载的调用 |
---|---|
无值(省略参数) | Optional |
单个值 | Optional |
采用逗号分隔列表形式的两个或更多值 | ParamArray |
任何长度的数组(包括空数组) | ParamArray |