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

为什么不做任何事情的语句不抛出异常(或警告开发人员)?

  •  1
  • SqlRyan  · 技术社区  · 15 年前

    我已经被vb.net中的语句咬了几次(不确定这种效果是否存在于c),这些语句似乎是自引用的,但是在执行它们时,它们实际上不做任何事情,因为它们需要一个目标,而没有提供一个目标。例如:

    Dim MyString as string = "String to test"
    
    ' Neither of these lines do anything '
    MyString.Replace(" ", "-")
    MyString.Substring(0,5)
    
    ' This will return the original string, because neither statement did anything '
    Messagebox.Show(MyString)
    

    在这两种情况下,语句都需要一个目标来将结果赋给.NET,而我并没有给出它。是否有原因导致IDE/编译器没有警告我这种效果,或者没有引发异常“statementdoesntdoanything”?因为代码的形成方式是永远不会改变任何东西的,所以它显然是错误的类型。

    8 回复  |  直到 15 年前
        1
  •  3
  •   Roger Pate    15 年前

    很难说忽略返回值不是有意的,因为有些函数会产生一些副作用并返回一个值。

    那些“仅仅”返回值的函数必须被标记为这样,以便让编译器检查它们,而这些函数并不是优先级,或者被判断为具有足够的投资回报(显然,否则它们会这样做)。

        2
  •  4
  •   codymanix    15 年前

    是的,如果没有副作用的方法可以用某种类型的[NoSideeffectsAttribute()]标记,以便编译器之类的工具可以警告您,那就太好了,但目前我还不知道这类事情。

    但您可以尝试fxcop,它可以在.NET程序集上发现许多细微的编程错误。

        3
  •  2
  •   Vincent Ramdhanie    15 年前

    在许多实例中,方法返回的值是由程序员可选地处理的。编译器无法知道这个特定的方法什么也不做。它可能会产生副作用,而且您选择不使用方法的返回值这一事实必须由您自己做出一个简洁的决定。

    如果编译器选择警告您发生这种情况的每个实例,那么您将收到太多的错误警告。

        4
  •  1
  •   Stephen Curial    15 年前

    编译器通常很难确定函数是否“做了什么”。除非编译器严格执行 Inter-Procedural Analysis (ipa),它无法确定函数调用是否有副作用。

    IPA是一个缓慢的过程,它显著地增加了编译器的内存需求,因此默认情况下大多数编译器都不执行此操作。

        5
  •  0
  •   Charles Bretana    15 年前

    这是继承的行为,从C,C++,是东方的,这样你就可以选择是否使用返回值从一个函数/方法…当你写一个函数/方法,它可以做很多事情,然后返回一些值,当你调用它时,你可以选择写

    variableName = functionName([parameterlist]);  
    

    如果您想在某些内容中使用返回值,或者

    functionName([parameterlist]);  
    

    如果你不这样做。

    对于没有副作用的函数方法(如您所提到的那些方法),如您所指出的,这是不太合理的,但是将其更改为新语言将与许多其他语言的悠久历史背道而驰,这些语言符合此标准…

        6
  •  0
  •   David Brunelle    15 年前

    我不确定是否还有另外一个关键字来强制或不将返回值放入变量中,这是一个好主意,原因有很多。

    1)假设您在返回值为optinal(因此通常是强制的)时添加一个关键字会导致大量代码停止编译或发出大量警告。

    2)假设您执行相反的操作,在强制返回值时添加一个关键字,有些人会简单地使用虚拟变量来存储它们,并像以前那样继续使用它。

    3)我不认为很多人会花时间去考虑回报值是否是可选的。在某些情况下,我必须承认它是被给予的,但并非总是如此。

        7
  •  0
  •   Dan Tao    15 年前

    考虑一下这个方法 Dictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value) :检查键是否在字典中,如果在字典中,则将值放入 out 参数。返回值为 bool 指示操作是否成功。有时你会在意,有时你不会。我认为对于这种方法,这是一种很好接受的方法;如果编译器强迫你将返回值赋给一个变量,人们会有很多这样的代码:

    int someValue = 0;
    bool discard = IntDictionary.TryGetValue("key", out someValue);
    
    // I don't even care if discard is true or false;
    // someValue will be 0 if it wasn't in IntDictionary
    
        8
  •  -1
  •   yfeldblum    15 年前

    我被咬了几次

    下结论,而不是

    VB.NET中的语句…那个…其实什么都不做

    但事实上这些都有很好的记录。