COM互操作方法签名中的ByRef

4

我有一个C#程序,调用了一个名为test的COM DLL方法,该方法有两个参数:第一个参数是通过ByVal传递的,第二个参数是通过ByRef传递的。

这就是COM DLL的功能:

Public Sub test(ByVal a As String, ByRef b As String)
    a = "a"
    b = "b"
End Sub

以下是C#程序的功能:

test.Class1 x = new test.Class1();
            string a = "1";
            string b = "2";
            x.test(a, ref b);

我注意到如果我删除ref关键字,编译器不会提醒我错过了ref关键字并传递ByVal参数。如果我错过了ref关键字,这可能是一个大问题,因为我只能在知道它需要ref之前才能注意到它。你知道为什么编译器会展现这种行为吗?


@MartinVerjans,在C#项目中不存在“Option Strict ON”。 - CRK
@HansPassant,我在没有使用 ref 关键字的情况下测试了该程序,它不会改变字符串的值。因此,如果您不告诉他这样做,请通过 ByVal 传递字符串。 - CRK
1个回答

6
这段内容与COM互操作代码和C#语言版本4有关系。在这种情况下,可以省略ref。C#版本4的许多调整都是为了使Office编程更加容易。Office API最初是设计用于早期VB版本的,并且默认使用ByRef。这对于VBA仍然适用。因此,尽管它们实际上不修改传递的参数,但API具有很多方法参数是ByRef的。

如果必要,编译器会生成一个临时变量以使调用合法。这会导致您的变量没有更新。这是需要注意的问题。两步前进,一步后退 :)


如果我有一个大型项目,并想检查每个遗漏的“ref”关键字,我该如何做?或者有什么建议可以让我发现这个错误吗? - CRK
哎呀,你必须使用显而易见的方法来查找代码中的错误,你需要使用调试器。不要惊慌,仅仅因为你犯了一个错误并不意味着你所有的都错了。IntelliSense 仍然可以帮助你正确地完成它。首先修复那个 COM 代码,它应该是一个函数。 - Hans Passant
也许你不理解我的问题。问题就在于:如果我在COM方法签名中漏掉了一个ref关键字,编译器仍会接受它而不会发出任何警告,即使实际上该方法需要一个ByRef参数。在一个大型项目中,我无法检查每个单独的方法及其签名(我可以,但这需要很多时间)。我只想让编译器在我漏掉ref关键字时提醒我。 - CRK
我很确定我理解了你的问题。也许你不明白“一步后退”的意思。它意味着在第4个版本中添加了一个新的潜在问题。虽然不难调试,但很明显该值没有改变。不要惊慌。 - Hans Passant
如果您只需要检查几个变量,那么这是显而易见的。但是如果您需要检查成千上万个变量呢?难道没有任何方法可以提醒我忘记使用ref关键字吗? - CRK
4
叹气,你不会放弃,对吧?好的,写一个Roslyn代码分析器,您可以将调用与方法声明进行比较并查看不匹配之处。在谷歌上搜索“编写Roslyn代码分析器”以获得相关信息。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接