代码之家  ›  专栏  ›  技术社区  ›  Nick

当函数没有返回时,vb.net中没有警告

  •  5
  • Nick  · 技术社区  · 15 年前

    Some comments on Stack Overflow question Why doesn't the C# compiler stop properties from referring to themselves? 关于警告让我想到了一些老问题,当我写更多的vb.net代码时,这些老问题总是把我搞糊涂。

    其中一个事实是,如果声明了函数,编译器不会发出警告,但从未对函数名执行显式的返回语句或赋值。在运行Visual Studio 2008时,我刚做了一个小型的实验项目,似乎这种行为从未被纠正过。我创建了一个VisualBasic控制台应用程序,代码如下:

    Module MainModule
    
        Sub Main()
    
            Dim test As Boolean = TestWarning()
    
        End Sub
    
        Function TestWarning() As Boolean
    
            Console.WriteLine("There is no Return Statement")
    
        End Function
    
    End Module
    

    我也进入了项目设置并 On Option Strict Option Explicit . 我还设置了警告配置,以便将“无返回值的函数/运算符”设置为错误。

    我编译了这个项目,没有得到任何警告,并且在testwarning()函数上也没有任何错误。这似乎是个警告的好地方,因为它会默认为假,而你可能只是忘记了做一个返回。C将在没有返回语句的情况下出错。我认为vb.net对“没有返回值的函数/运算符”配置做了同样的事情。这是个虫子,还是有什么东西我找不到?

    进一步实验

    Function TestWarning() As Boolean
    
        If DateTime.Now.DayOfWeek = DayOfWeek.Monday Then
            Return False
        Else
            Console.WriteLine("There is no Return Statement")
        End If
    
    End Function
    

    如果我有明确的 Return 在一个 If 而且里面什么都没有 Else 也没有警告或错误。它只采用默认值,即使您可能希望(通过编程风格)有一个显式的返回。在这种情况下,我明确地返回 False (这是布尔值的默认值),所以很可能是一个隐藏的bug,我应该返回它 True 否则 .

    5 回复  |  直到 8 年前
        1
  •  7
  •   GSerg    15 年前

    警告只会让您知道函数何时返回 Nothing 默认情况下。

    如果返回值是引用类型,则会收到警告。

    但是您的函数有一个值类型的返回值,这些值不能是 没有什么 . 因此,没有警告。

    这是因为这个函数中的函数名充当结果变量。通过将值分配给函数名而不是使用 Return . 所有变量都初始化为默认值,包括函数名变量。情况并非如此 C 因此警告的含义不同。

    在初始化变量之前将其与使用变量进行比较:

    Dim x As Integer
    CallFunction(x)  'No warning, x is implicitly and properly initialized to 0.
    
    Dim y as Object
    CallFunction(y)  'A warning: variable used before a value is assigned to it
    
        2
  •  6
  •   Peter Mortensen icecrime    12 年前

    它是基本语言的一部分。所有基本函数都有返回类型。如果不指定返回类型,则假定该类型为 对象 .

    因此编译器不能警告您丢失的返回,因为它不知道您是有意跳过返回,还是因为您利用了该语言的默认返回值特性。

    由此 http://msdn.microsoft.com/en-us/library/sect4ck6(VS.80).aspx

    如果使用exit函数而不为name赋值,则过程将返回在returnType中指定的数据类型的默认值。如果未指定返回类型,则过程将不返回任何内容,即对象的默认值。

        3
  •  0
  •   rh.    15 年前

    对我来说,那看起来像个虫子。我可以在VS2008 SP1中复制它。

    有趣的是,如果它是一个引用类型,它就可以工作,但是如果它是一个值类型,它就不能工作。

        4
  •  0
  •   Peter Mortensen icecrime    9 年前

    您不一定需要一个变通方案,但我只是在想:您可以使函数的返回类型 Nullable .

    在运行时,如果函数没有反映任何内容,您知道程序员没有显式地分配返回值。当然,这只适用于自然不返回任何值的函数。而且在很多方面效率低下。

        5
  •  0
  •   Peter Mortensen icecrime    8 年前

    我为同样的问题浪费了七个小时。在我的情况下(使用Visual Studio 2012),编译以编译错误结束:

    错误:未能复制文件“obj\x86 debug \<name of the build target>.exe”,因为找不到该文件。(0, 0)

    (文本是从德语错误信息中翻译出来的,我希望它能被正确翻译。)

    由于这条消息没有帮助,我将我的项目还原到它编译的状态,并最终跟踪到类似于以下内容的内容:

    Function SomeFunction() as Boolean
      If <somecondition> then 
        Exit Function
      end if
    end function
    

    如果我将exit函数替换为return false,或者插入somefunction=false,那么编译器错误将不会出现。

    所以是的,正如前面所述,VisualBasic应该将返回值默认为返回类型的默认值,但是它以某种方式破坏了编译。

    我怀疑这种行为很难重现。我的底线是:显式设置返回值。它对代码更清楚,可能会节省7个小时的调试时间。