【问题标题】:Is there a VB.NET equivalent of C# out parameters?是否有与 C# 输出参数等效的 VB.NET?
【发布时间】:2010-12-05 12:21:36
【问题描述】:

VB.NET 是否有直接等价于 C#out 的函数参数,其中传递给函数的变量不需要初始化?

【问题讨论】:

    标签: vb.net c#-to-vb.net out-parameters


    【解决方案1】:

    不,VB 中没有 out 关键字的等效项。

    但是,VB 会自动初始化方法中的所有局部变量,因此您可以使用ByRef,而无需先显式初始化变量。

    例子:

    Sub Main()
      Dim y As Integer
      Test(y)
    End Sub
    
    Sub Test(ByRef x As Integer)
      x = 42
    End Sub
    

    (如果您检查框架中的代码(例如 Double.TryParse),您可能会看到 <OutAttribute> 添加到参数中,但这仅在为 COM 互操作或平台调用编组调用时才会有所不同。)

    【讨论】:

    • @Spolto:如果您要将 VBScript 转换为 VB,则应确保将 Explicit 和 Strict 模式设置为打开。它会给你更多的错误信息,但大多数会指向问题的根源(例如,没有类型声明的变量)而不是次要问题(例如,没有类型声明的变量变成Object,所以它不能用于@987654327 @参数)。
    • @Guffa:我不知道这是否是版本问题,但在将未初始化的 reference type 变量作为ByRef 参数传递时,我也会收到编译器警告。 (值类型参数不会发生这种情况。)
    • @Dan Tao,Spolto:这似乎是不同之处,我也收到了关于引用类型的警告。无法指定参数是语言的限制,您只需初始化变量即可摆脱警告。即使将Nothing 分配给他们也会消除警告,即使它不会改变结果。
    • @Guffa:是的,到目前为止,我一直将Nothing 分配给他们。这只是耗时,因为我不得不在一个大型遗留网站中进行数百次。感谢您的调查。
    • @MarkHurd:那么投票是不公平的,因为我已经提到Out 属性 等同于C# out 关键字。
    【解决方案2】:

    不,没有等效的构造允许将未初始化的变量传递给方法而不发出警告,但是,正如我在 question and answer 中提到的那样,在 ByRef 参数定义上指定了 <Out()> attribute,虽然VB 忽略它, 被 C# 视为out 参数。

    所以,我会将引用变量预初始化为 Nothing 指定 <Out()> ByRef 来表示意图(如果 C# 用户访问您的方法,这将起作用)。

    如果您知道何时打算在未分配的引用变量中访问默认Nothing,您可以将“警告配置”“分配前变量的使用”设置为 “无” 在项目级别(项目属性 > 编译,您可能希望在更改此设置之前将配置设置为“所有配置”),或者在 VS2015(VB.NET 14)中,您可以使用 @ 987654329@.

    【讨论】:

    • 这很重要。我有一个 MembershipProvider 的 VB 子类,然后是 VB 子类的 C# 子类。 C# 代码没有认识到 MembershipProvider 中的抽象方法已经实现的事实,直到我在 VB 类中为在 MembershipProvider 基类中指定为 out 的参数应用了属性。
    • @RichardCollette 这可能值得成为我链接问题的答案!
    【解决方案3】:

    C#版本

      void TestFunc(int x, ref int y, out int z) {
      x++;  
      y++;
      z = 5;
    }
    

    vb.net版

        Sub TestFunc(ByVal x As Integer, ByRef y As Integer, ByRef z As Integer)
      x += 1
      y += 1 
      z = 5 
    End Sub
    

    Found the answer here

    更新

    如评论中所述,不要忘记初始化将在输出槽中使用的参数

    【讨论】:

    • 总的来说,我同意ByRef是最接近out的东西。但是,如果您传递未初始化的变量,ByRef 仍会引发警告,如问题所问。
    • 我的反对意见是很久以前的:您链接的网站非常笼统;它没有列出具体问题、差异和技术细节。此外,您的回答仍然没有回答问题。
    【解决方案4】:

    我在 VB.NET 中遇到了一个问题,即我调用了一个“通过 ref”传递回数组的函数。

    即使编译器将其标记为警告,它也很好。修复非常简单,可能是很好的编程习惯。

    我变了

    Dim m_arr_values() as Integer
    
    fnRetArray(m_arr_values)
    

    ' Even though 'Nothing' is the default value, setting it
    ' stops the compiler complaining.
    Dim m_arr_values() as Integer = Nothing
    
    fnRetArray(m_arr_values)
    

    如果变量名称是描述性的,这在编码时也会有所帮助...

    Sub fnCreatePalette(ByRef arr_in_pal() As color, ByRef arr_out_pal() as uinteger)
        ...
    End Sub
    

    【讨论】:

    • 匈牙利符号违反 .NET 框架设计指南。
    【解决方案5】:

    您可以在 VB.NET 中使用按引用传递的方法。

    您需要 C# 中的 Out 参数机制,因为它不允许您在未初始化的情况下使用任何变量。

    VB.NET 不需要特殊关键字,因为它会自动完成。

    只需使用 ByRef。

    【讨论】:

    • 这没有回答问题,而且对于 C# 来说是错误的。
    • byref 允许您不初始化,并允许您更改参数值。但是,与 C# out 参数相反,它允许您使用值初始化参数并在函数中使用它,而在 C# 中,out 关键字强制您仅将其用作 out 参数而不是作为输入功能。此外,如果您没有在函数中更改或设置此参数的值,编译器不会将其捕获为错误,而 C# 则会发出编译错误。
    【解决方案6】:

    VB 具有应该与 C# 相同的属性,但今天即使您使用它仍然会收到警告。在 github 的 vblang 区域中有关于修复它的详细信息。 https://github.com/dotnet/vblang/issues/67.

    【讨论】:

      【解决方案7】:

      在变量前使用关键字ByRef

      【讨论】:

      • ByRef 相当于 C# 中的ref 参数,需要在传入函数之前进行初始化。
      猜你喜欢
      • 2012-01-21
      • 1970-01-01
      • 2014-08-06
      • 2021-04-30
      • 2017-01-01
      • 2023-03-30
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      相关资源
      最近更新 更多