【问题标题】:VB.NET Function ReturnVB.NET 函数返回
【发布时间】:2023-03-14 11:10:01
【问题描述】:

为了从 VB.NET 函数返回一个值,可以为“函数名称”分配一个值或使用“返回值”。

我有时会看到这些在同一个函数中混合在一起。就个人而言,我更喜欢退货。

我的问题是,如果有的话,两者之间的内部差异是什么?

【问题讨论】:

    标签: vb.net function return


    【解决方案1】:

    不同之处在于他们做不同的事情!

    “返回值”做了两件事:
    1. 设置该点的函数返回值 2. 立即退出函数

    函数中没有进一步的代码执行!

    'Functionname = value' 做了 1 件事: 1. 设置该点的函数返回值

    函数中的其他代码继续执行 这使得额外的逻辑可以细化或覆盖函数返回值

    巨大的差异伙计们。请记住,这不仅与状态有关,还与流程有关。

    【讨论】:

    • 他没有问这个。他询问使用返回值(不是语句)或将值分配给函数名称。
    • 他实际上是在“我的问题是,如果有的话,两者之间的内部差异是什么?
    • @StingyJack - 您将问题解释为“使用返回值(而非语句)”。我不确定这意味着什么,但我确实怀疑这里的共识是问题中的“返回值”短语中的“返回”确实指的是返回语句,而“值”指的是它的论点。在您对我的其他评论中,您将我推荐给stackoverflow.com/a/451149/16391,它使用一个简单的示例清楚地将分配 FunctionName 与使用 return 语句进行了比较。如上所述,使用任何重要的示例,IL 都会有所不同。
    【解决方案2】:

    让我们来看看......奇怪的是“functionName =”生成的IL更少?

    代码:

    Public Function Test() As String
        Test = "Test"
    End Function
    
    
    Public Function Test2() As String
        Return "Test"
    End Function
    

    IL:

    .method public static string Test() cil managed
    {
        .maxstack 1
        .locals init (
            [0] string Test)
        L_0000: nop 
        L_0001: ldstr "Test"
        L_0006: stloc.0 
        L_0007: ldloc.0 
        L_0008: ret 
    }
    
    .method public static string Test2() cil managed
    {
        .maxstack 1
        .locals init (
            [0] string Test2)
        L_0000: nop 
        L_0001: ldstr "Test"
        L_0006: stloc.0 
        L_0007: br.s L_0009
        L_0009: ldloc.0 
        L_000a: ret 
    }
    

    【讨论】:

    • 有趣:隐式返回保存了一条指令。
    • 好帖子。为什么需要到 L_0009 的分支?也许只是因为回报没有被优化掉?
    • return 兼容 C# 对更多程序员来说更具可读性,听起来更好
    • Rulas,您的评论无关紧要且毫无道理,请在评论前阅读所有回复和cmets。
    • 需要注意的是,这只是在调试模式下(因此,无关紧要)!在发布模式下,生成相同的代码。
    【解决方案3】:

    可能没有区别。 IIRC,编译器生成的 IL 将它们都转换为 Return 语句除非额外使用 _returnValue 变量

    在我看来,FunctionName 赋值的可读性很差,是 VB6 坏习惯的一个例子。我也更喜欢 _returnValue (NOT RETVAL) 变量方法。

    【讨论】:

    • 下面的答案是更好的答案
    • @Jonathan - SO 问题的答案并不总是以相同的方式排序。你可以链接到帖子吗?
    • 这个答案是完全错误的。 IL 不会将函数名的赋值转换为 return 语句,因为该赋值不会导致函数在那时返回。只有在没有参数的情况下或在“结束函数”调用 return 语句时,赋值的值才会返回。
    • @MichaelKrebs - 你确定吗?在发布模式下编译在简单的示例中显示了相同的内容。另一个例子见stackoverflow.com/a/451149/16391
    • @StingyJack - 是的,我确定。 IL 仅在琐碎示例中相同,并且仅在发布模式下。 FunctionName 赋值之后的函数中的任何代码都将被执行,而 Return 调用之后的函数中的任何代码都不会执行。这是一个巨大的行为差异,在发布和调试模式下,总是显示为 IL 中的差异,如果后面还有一行代码的话。它也与“两者之间的内部差异(如果有的话)是什么?”这个问题高度相关?
    【解决方案4】:

    以下操作仅供Visual Basic 6.0 开发人员轻松移植代码:

    Public Function MyFunction() As String
        MyFunction = "Hello"
    End Function
    

    如果您的项目包括没有使用过 Visual Basic 6.0 的任何人,我绝对不建议继续这样做,因为这种语法会令人困惑。

    【讨论】:

    • 我也在摸不着头脑......平衡。
    • 我的问题是两者之间的内部差异是什么,而不是偏好或最佳实践。
    • 为什么你会推荐一件事而不是另一件事的一些解释会很好。
    • 该帖子还带有“你”字样的攻击性和冒犯性。尤其是在这种情况下,它与我的帖子相矛盾。
    • 删除了最后一点,因为它不需要,谢谢指出,这就是我第一次醒来时写的东西! :)
    【解决方案5】:

    100 次中有 99 次我会使用“返回值”。

    每隔一段时间,我都会有一个函数,其中另一种类型不仅允许我保存变量声明,而且以一种实际上显着澄清函数的方式进行。通常,当我想将返回值命名为与函数相同时,通常会发生这种情况,并且通常这些是递归函数;关于该构造的某些东西将其借给了隐式返回变量。但是,这种情况极为罕见。我不知道我当前的项目中是否有任何使用隐式返回变量的函数。

    【讨论】:

      【解决方案6】:

      当工具/选项/文本编辑器/所有语言/代码镜头被激活时,引用计数显示在每个子、函数或属性语句的上方。

      “返回值”似乎比“为函数名称赋值”更好。在后一种情况下,“代码镜头”会产生一个膨胀的引用计数。

      ' Code Lens reports "0 references" here for Sub Rosa().
      Public Sub Rosa()
          Diagnostics.Debug.WriteLine(Test())
          Diagnostics.Debug.WriteLine(Test2())
      End Sub
      
      ' Code Lens reports "2 references" here for Function Test().
      Public Function Test() As String
          Test = "Test"       ' Code Lens counts this as a reference.
      End Function
      
      ' Code Lens reports "1 reference" here for Function Test2().
      Public Function Test2() As String
          Dim strTest2 as String = "Test"
          Return strTest2     ' Code Lens does NOT count this as a reference.
      End Function
      

      【讨论】:

      • 在我看来,关于引用计数膨胀的观点值得考虑。
      【解决方案7】:

      读到返回值语法是 One True .NET 做事方式后,我想“好吧,我们就那样做”。然后我写了一个我知道的函数,手头知道,在任何情况下都从 Return 语句返回一个值,或者返回一个异常,并且仍然得到一个编译器警告,该函数“不会在所有路径上返回一个值” .

      谢天谢地,我遇到了 Stack Overflow 问题 How can I make this function not generate a “doesn't return a value on all paths” warning?,它解释了原因;在函数开头为过程名称添加默认值分配也可以防止出现警告。

      因此,即使我将继续使用返回值语法只是为了语法一致性,我也会为函数名称分配一个默认值,以防止编译过程混乱虚假警告。

      【讨论】:

        【解决方案8】:

        在使用 3rd 方工厂 (_hsf) 时非常方便,您可以避免声明返回变量

        Public Function CreateExtremum(iShape As INFITF.Reference, iDir1 As HybridShapeTypeLib.HybridShapeDirection, iSide1 As Integer, iDir2 As HybridShapeTypeLib.HybridShapeDirection, iSide2 As Integer, iDir3 As HybridShapeTypeLib.HybridShapeDirection, iSide3 As Integer) As HybridShapeTypeLib.HybridShapeExtremum
            CreateExtremum = _hsf.AddNewExtremum(iShape, iDir1, iSide1)
            CreateExtremum.Direction2 = iDir2
            CreateExtremum.ExtremumType2 = iSide2
            CreateExtremum.Direction3 = iDir3
            CreateExtremum.ExtremumType3 = iSide3
            CreateExtremum.Compute()
        End Function
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-05
          • 2018-03-28
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          • 1970-01-01
          • 2011-10-21
          • 1970-01-01
          相关资源
          最近更新 更多