c# - 哪种方法重载可以从 VBScript 访问?

标签 c# vbscript overloading

<分区>

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

public virtual int IndexOf(Object value)
public virtual int IndexOf(Object value, int startIndex)
public virtual int IndexOf(Object value, int startIndex, int count)

在 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'

'Overloading a method in com visible dll'汉斯帕桑特解释说 程序集中存在重载方法,但无法从脚本中获取它们 dispid 因此称呼他们。这似乎意味着一种方法可能会成功。

  • 我可以从 ArrayList 源代码(或其他地方)确定哪个方法可以访问吗?管理此选择过程的规则是什么?
  • 为什么情况一和情况三的错误消息不同?

最佳答案

简答:全部。


让我们分析一下@hans-passant已写;

Answer to Overloading a method in com visible dll
COM does not have support for member overloads, each name must be unique. An inevitable side-effect of IDispatch::GetIDsOfNames(). The function that the script interpreter uses to translate "Write" as used in the scripting code to a dispid. The method still exists, there's just no way to get GetIDsOfNames() to return its dispid. The type library exporter solves this problem by renaming the overloaded method, it will be Write_2().

分为两部分

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

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

所以所有三个重载都可用,只是使用以下格式重命名

oList.IndexOf
oList.IndexOf_2
oList.IndexOf_3

Note: There is no IndexOf_1 because the first overload always takes the original method name and subsequent overloads start from _2 onwards.

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

快速尝试测试

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")

输出:

1
-1
1

为什么这两个语句会因不同的错误而失败?

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

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'

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

oList.IndexOf "foo"

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

Invalid procedure call or argument: 'IndexOf'

第三条语句

oList.IndexOf "foo", 0, 1

比预期的签名多包含一个参数,因此不是没有找到匹配,而是找到一个匹配但报告;

Wrong number of arguments or property assignment was not valid: 'IndexOf'

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


有用的链接

关于c# - 哪种方法重载可以从 VBScript 访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37001439/

相关文章:

scripting - Visual Basic 脚本动态数组

c++ - 重载一个可以区分非静态成员方法和其他函数的模板函数

c# - 无法重载具有类型约束的泛型方法

c# - 在 C#/.NET 中将参数标记为 NOT nullable?

c# - 如何将小于 1 的字符串 ("0.25500000") 转换为十进制?

c# - Visual Basic 2010 登录 View asp.net

c# - 如何简化我的代码? (在行列表中搜索最小和最大坐标)

vbscript - 如何将字典添加到数组中

c++ - 为什么不能覆盖涉及第三方代码的模板类的 operator<<?

windows - 如何在 Windows VBS 脚本上更改语音