【问题标题】:When does = perform comparison instead of assignment?= 什么时候执行比较而不是赋值?
【发布时间】:2013-10-17 16:26:14
【问题描述】:

在 VB.NET 中,没有用于比较的 == 运算符,因此 = 运算符用于此目的以及赋值。我有一个函数,我希望它返回比较的布尔结果,而不是将结果存储在变量中:

Private Function foo() As Boolean
    Dim bar As Integer = 1
    Return bar = 2
End Function

返回:False

好的,但是bar 的值是多少?

Private Function foo() As KeyValuePair(Of Boolean, Integer)
    Dim bar As Integer = 1
    Return New KeyValuePair(Of Boolean, Integer)(bar = 2, bar)
End Function

返回:False, 1

看起来= 会在语句上下文需要时执行比较,但这有保证吗?也就是说,我可以确定bar 在这种情况下永远不会设置为 2 吗?

另外,我知道 VB.NET 不允许链式内联赋值,may be for the best。这种奇怪的= 行为是否会引起我应该注意的任何其他怪癖?

【问题讨论】:

  • 在您的第一个示例中,将 Dim 更改为 Static 并在返回处放置一个断点。然后根据需要经常调用 foo,您会看到 bar 仍然是 1。其他发帖人之一指出,如果语句之前还有其他关键字,则 '=' 返回一个布尔值。

标签: vb.net


【解决方案1】:

你不能在 VB 中进行内联赋值,赋值是一个显式语句:

[Let] <<target-reference>> = <<value-expression>>

Let 是可选的和隐含的,几乎不再使用。您可以用来区分[Let] 命令和相等测试的一般规则是,对于Let,语句中的目标引用之前不能有其他关键字。 AFAIK,在所有= 作为相等测试的情况下,语句中前面都有一个或多个其他关键字。

在您的第一个示例中,关键字 Return 在您的 = 之前,因此这是一个相等测试,而不是一个赋值。

在您的第一个示例中,您可以执行以下任一操作:

Return 2

bar = 2
Return bar

至于你的问题“好的,但是 bar 的值是多少?”,bar 仍然等于 1。

= 在 VB 中不会引起怪癖。它的工作方式与文档完全一致,并且一直如此(包括其前身 BASIC,可追溯到 1968 年)。

【讨论】:

    【解决方案2】:

    如果您开始使用 VB(来自 C# 之类的语言)编写代码,您应该开始习惯 VB 特有的做事方式;这是基于这样的想法:对程序员来说尽可能简单和直观。 “如果分配和比较总是发生在不同的上下文中,为什么不使用相同的运算符并让上下文定义其确切含义呢?” -> VB 看待事物的方式。 “不,不同的运营商必须考虑不同的现实。讨论结束”-> C#-way。 :)

    这可靠吗?你能盲目相信这些对程序员来说并不总是清楚的位吗?当然,VB.NET 的特性是高度可靠和值得信赖的。您始终可以使用=(或在某些情况下使用Is,但VS 会告诉您)并完全确定代码会执行预期的操作。但问题是:你确定你写的正是你想要的吗?

    最后一个问题可能是对 VB 的批评,以及可能会给其他语言的程序员带来一些问题:灵活性越高,出错的可能性就越大;主要是如果你习惯了不同的格式。

    关于链式内联赋值,老实说,我看不到它的真正用途(并且从不在 C# 中使用它们)。关于 C# 的其他差异,还有很多;在某些情况下,我认为 C# 方法更好;其他时候,VB.NET 之一。关于代码的可读性/长度,我可以参考With Statement,我一直发现它在某种程度上很有用,而这在 C# 中是不存在的。

    【讨论】:

    • “特殊性”似乎没有根据,因为 VB 的句法和语义风格源自 BASIC/Fortan/COBOL,它们都比 C 早了很多年,并且是几十年来的主导风格。
    • @RBarryYoung 如果您阅读了我所有的答案,您会发现我并没有为任何方法辩护。我什至不是从一般的角度谈论,而是从 OP(C# 程序员)的角度谈论。无论如何,您的评论当然是值得的:您认为这两个 cmet 足以说明这一点还是我应该换一个更合适的词(或澄清它)?
    • 谢谢,这很好。让它站起来。
    【解决方案3】:

    100% 确定表达式将被评估为布尔表达式的一种方法是使用 ()

    例如

    Dim a = 2
    Return (a = 1)
    

    由于您不能在括号内为变量设置值。

    我想说的是:例如,在返回状态中,即使您使用

    ,您也不能将值分配给变量
    a = 1
    

    编译器知道这个表达式只能是布尔表达式。

    if 语句也一样..

    【讨论】:

    • 无论哪种方式,您都 100% 确定
    • 我喜欢这个,即使括号不是必需的。我认为它使意图更加明显。
    【解决方案4】:

    嘿,在 QB45 天,我们曾经利用“True”是数值 -1 的事实。所以你会看到像x = 1 - x * (x &lt; 6)这样的代码(翻译:增加x,但是当它达到6时重置为1)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-08
      • 2018-09-12
      • 2017-08-04
      • 2011-02-21
      • 1970-01-01
      • 2015-06-25
      • 2012-10-24
      • 1970-01-01
      相关资源
      最近更新 更多