有没有更好的方法来编写以下VB6代码段?

时间:2012-07-20 00:56:42

标签: vb6 styles short-circuiting select-case

我在$ COMPANY工作,我正在帮助维持$ LEGACY_APPLICATION。它是用visual basic 6编写的。

由于缺乏VB6在if语句中执行短路评估的能力(这将简化这一点),我面临着做一个令人不快的精心嵌套的if语句。我也试过AndAlso,但无济于事。必须是VB6之后添加的功能。

SO上的一些天才指出,如果你有耐心的话,你可以把一个精选案例陈述变成像短语if语句一样,所以我试过了,这就是我想出的:

Select Case (True) ' pretend this is an if-else statement
    Case (item Is Nothing): Exit Sub ' we got a non-element
    Case ((item Is Not Nothing) And (lastSelected Is Nothing)): Set lastSelected = item ' we got our first good element
    Case (item = lastSelected): Exit Sub ' we already had what we got
    Case (Not item = lastSelected): Set lastSelected = item ' we got something new
End Select

这绝对有点不寻常,我不得不使用我梦幻般的白板(顺便提一下,除了计算机之外,它几乎是最有用的编程资源),以确保我已正确映射所有语句。

这是在那里发生的事情:我有一个昂贵的操作,我希望尽可能避免重复。 lastSelected是对最近传递给此计算的值的持久引用。 item是刚刚从GUI接收的参数。如果之前从未调用过该程序,则lastSelected从Nothing开始。项目也可以没什么。此外,如果lastSelected和item都是相同的内容,请跳过计算。

如果我用C ++写这个,我会写:

if (item == NULL || (lastSelected != NULL && item->operator==(*lastSelected))) return;
else lastSelected = item;

但是,我不是。

问题

如何重写这个以使其更好看并更有意义?对于说“是,这是为什么:X,Y,Z”或“否,以及为什么不是:X,Y,Z”的答案,将给予赞成票。

编辑

修正了C ++语句以匹配VB6语句(它们应该是等效的)

4 个答案:

答案 0 :(得分:4)

这个更短,可读性高100倍。

编辑 Wug编辑了MarkJ原始答案中的代码,进入:

If (item Is Nothing)
    Then Exit Sub ' we got a non-element
ElseIf (lastSelected Is Nothing) Then
    Set lastSelected = item ' we got our first go 
ElseIf (item = lastSelected) Then
    Exit Sub ' we already had what we got
End If
Set lastSelected = item ' we got something new 

这是MarkJ的回复编辑。一个嵌套if,但只有一个Set。对我来说似乎更整洁。

If (item Is Nothing) Then 
  Exit Sub ' we got a non-element 
ElseIf Not (lastSelected Is Nothing) Then ' not our first go
  If (item = lastSelected) Then 
    Exit Sub ' we already had what we got 
  End If 
End If
Set lastSelected = item ' we got something new
' does stuff here? @Wug is that true?
  • 要比较VB6中的引用相等性,请使用项目Is LastSelected。因为item = lastSelected可能会评估对象中的默认属性并进行比较!
  • 由于简洁似乎是一个目标,请考虑这一点。如果在条件X为True时退出Sub,则以后不需要再次检查X.这是假的!除非它在评估之间改变其值(例如,X是检查系统时钟的函数)。您正在检查项目是否为lastSelected,然后是否为。如果item Is Nothing是False,请不要费心检查item Is Is Nothing是否为True!
  • VB6不会导致backwards compatibility with ancient versions of Basic
  • 短路
  • 不要担心VB6不是其他语言而放松!

答案 1 :(得分:3)

YES

我从你的个案陈述中翻译了它。我觉得个人阅读更容易。

If Item Is Nothing Then
  Exit Sub ' we got a non-element
ElseIf LastSelected Is Nothing Then
  Set LastSelected = Item ' we got our first good element
ElseIf Item = LastSelectedItem Then
  Exit Sub ' we already had what we got
Else
  Set LastSelected = Item ' we got something new
End If

你要求解释。我试着不必付出太多(通过重新使用你自己的代码注释)。

但无论如何这是: - )

  • 首先,如果没有项目,请退出。容易。
  • 否则,如果LastSelected Is Nothing我们知道,因为第一个if条件失败,Item存在,并且可以将该值标记为Last Selection。如你所说,我们得到了第一个好元素。该子继续。
  • 但是,如果我们有ItemLastSelected的现有值,那么它们是否相等。如果他们是平等的,那就退出。
  • 如果不相等,请更新LastSelected。如你所说,我们有新的东西

答案 2 :(得分:1)

你可以使用这样的辅助函数:

Private Function pvGetItemData(oItem As ListItem) As Variant
    If Not oItem Is Nothing Then
        pvGetItemData = oItem.Tag
    Else
        pvGetItemData = -1
    End If
End Function

然后

If pvGetItemData(Item) = pvGetItemData(LastSelected) Then
    ' cache hit
Else
    ' do calc
    Set LastSelected = Item
End If

答案 3 :(得分:0)

YES

我会更简单:

If item Is Nothing Then
  Exit Sub ' we got a non-element
Else
  Set lastSelected = item ' we got something to assign
End If

除非有分配lastItem的副作用(它可以是具有无效赋值代码的属性),否则代码逻辑基本相同。

如果你不需要退出sub(片段在sub或者某个东西的末尾),那么接下来就更简单了:

If Not (item Is Nothing) Then Set lastSelected = item
顺便说一句,你的Select Case (True)看起来对VB程序员来说真的很奇怪:)