VB.NET 函数返回

Posted

技术标签:

【中文标题】VB.NET 函数返回【英文标题】:VB.NET Function Return 【发布时间】:2010-10-01 20:23:55 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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

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

【讨论】:

他没有问这个。他询问使用返回值(不是语句)或将值分配给函数名称。 他实际上是在“我的问题是,如果有的话,两者之间的内部差异是什么? @StingyJack - 您将问题解释为“使用返回值(而非语句)”。我不确定这意味着什么,但我确实怀疑这里的共识是问题中的“返回值”短语中的“返回”确实指的是返回语句,而“值”指的是它的论点。在您对我的其他评论中,您将我推荐给***.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 - 你确定吗?在发布模式下编译在简单的示例中显示了相同的内容。另一个例子见***.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

【讨论】:

以上是关于VB.NET 函数返回的主要内容,如果未能解决你的问题,请参考以下文章

VB.net OleDbDataReader 不返回想要的值

VB.NET中“FunctionName = value”和“Return value”的区别?

VB.NET MySQL 查询不返回值

将值从 SQL Server 返回到 VB.Net

VB .NET OleDbCommand 在 SQL 语句末尾返回缺少分号 (;)

当 url 正确时,VB.NET webrequest 返回 404