可以从 VBScript 访问哪个方法重载?

Mic*_*ann 5 c# vbscript overloading

System.Collections.ArrayListComVisible(true)。它包含三个重载IndexOf(参见此处):

public virtual int IndexOf(Object value)
public virtual int IndexOf(Object value, int startIndex)
public virtual int IndexOf(Object value, int startIndex, int count)
Run Code Online (Sandbox Code Playgroud)

从 VBScript 中,只能访问第二个重载:

Dim oList
Set oList = CreateObject("System.Collections.ArrayList")

'oList.IndexOf "foo"        'Error: Invalid procedure call or argument: 'IndexOf'
 oList.IndexOf "foo", 0
'oList.IndexOf "foo", 0, 1  'Error: Wrong number of arguments or property assignment was not valid: 'IndexOf'
Run Code Online (Sandbox Code Playgroud)

“重载 com 可见 dll 中的方法”中, Hans Passant 解释说程序集中存在重载方法,但从脚本中无法获得它们的 dispid,因此调用它们。这似乎意味着一种方法可能会通过。

  • 我可以从 ArrayList 源(或其他地方)确定哪个方法可以访问?管理这个选择过程的规则是什么?
  • 为什么案例一和案例三的错误信息不同?

Lan*_*art 3

简短回答:全部。


让我们分析一下@hans-passant写的内容;

重载 com 可见 dll 中的方法的回答COM
不支持成员重载,每个名称必须是唯一的。不可避免的副作用IDispatch::GetIDsOfNames()。脚本解释器用于将脚本代码中使用的“Write”转换为 dispid 的函数。该方法仍然存在,只是没有办法GetIDsOfNames()返回其 dispid。类型库导出器通过重命名重载方法解决了这个问题,它将是Write_2().

它分为两部分

  1. 解释的行为IDispatch::GetIDsOfNames()
  2. 类型库导出器如何解决唯一性问题。

这并不是说它们不可用,相反,它们已被重命名以避免分配给方法名称IDispatch::GetIDsOfNames()时的唯一性约束。DISPID

因此,所有三个重载都可用,只需使用以下格式重命名即可

oList.IndexOf
oList.IndexOf_2
oList.IndexOf_3
Run Code Online (Sandbox Code Playgroud)

注意:没有IndexOf_1,因为第一个重载始终采用原始方法名称,后续重载从_2这里开始。

根据类型库导出器重命名重载的方式,重载将取决于哪个重载采用哪组参数,解决此问题的唯一方法是反复试验。

快速尝试测试

Dim oList
Set oList = CreateObject("System.Collections.ArrayList")

oList.Add "bar"
oList.Add "foo"

WScript.Echo oList.IndexOf("foo", 0)
WScript.Echo oList.IndexOf_2("foo", 0, 1)
WScript.Echo oList.IndexOf_3("foo")
Run Code Online (Sandbox Code Playgroud)

输出:

1
-1
1
Run Code Online (Sandbox Code Playgroud)

为什么这两个语句会失败并出现不同的错误?

如果我们回到你原来的例子

Dim oList
Set oList = CreateObject("System.Collections.ArrayList")

'oList.IndexOf "foo"        'Error: Invalid procedure call or argument: 'IndexOf'
 oList.IndexOf "foo", 0
'oList.IndexOf "foo", 0, 1  'Error: Wrong number of arguments or property assignment was not valid: 'IndexOf'
Run Code Online (Sandbox Code Playgroud)

由于 VBScript 计算方法签名的方式不同,语句一和语句三失败并出现不同的错误。上例中的正确签名接受两个参数,因此第一个语句;

oList.IndexOf "foo"
Run Code Online (Sandbox Code Playgroud)

将失败,因为唯一匹配的签名有两个参数,而不是一个,因此会出现错误;

无效的过程调用或参数:“IndexOf”

第三个声明

oList.IndexOf "foo", 0, 1
Run Code Online (Sandbox Code Playgroud)

比预期签名还包含一个参数,因此它不会找到匹配项,而是找到一个匹配项,但会报告;

参数数量错误或属性分配无效:“IndexOf”

因为参数的数量超出了方法签名的预期IndexOf(arg, arg)


有用的链接