什么时候应该使用With-End With?何时应该在VB6中使用普通对象引用?

时间:2011-04-20 14:46:39

标签: optimization syntax vb6

仔细阅读我维护的代码,我发现在某些地方使用With - End With构造...

With my_object
    .do_this()
    .do_that()
    .do_the_other()
End With

有时更直接

my_object.do_this()
my_object.do_that()
my_object.do_the_other()

这两种形式之间是否存在细微差别?总的来说,我应该选择哪个?

(我的个人观点是,我选择了第二次,因为在第一次开始让我的头受伤之后,有两到三次嵌套 - 这是一个充分的理由吗?)

4 个答案:

答案 0 :(得分:4)

如果对象引用实际上是一个更复杂的表达式,如属性getter或函数的返回值,则会有所不同。

比较一下:

With MyObjectFactory.CreateMyObject()
    .do_this
    .do_that
    .WriteToDatabase
End With

反对明显错误的:

MyObjectFactory.CreateMyObject().do_this
MyObjectFactory.CreateMyObject().do_that
MyObjectFactory.CreateMyObject().WriteToDatabase

在这种情况下,实际的等价物是创建一个引用:

Dim myObject as MyObject
Set myObject = MyObjectFactory.CreateMyObject() 
myObject.do_this
myObject.do_that
myObject.WriteToDatabase

至于你是否应该使用With blocks,这实际上是个人喜好的问题。像你一样,我肯定会发现许多嵌套的块令人困惑。这可能也是该功能应分成多个功能的标志。

答案 1 :(得分:2)

贾斯汀不对。 With...End With构造不仅仅是语法糖果,它也是一种性能技巧。如果您的对象路径包含多个点(。),则性能提升非常明显,尤其是在循环和/或处理Types(结构)时。

例如,这段代码:

For x = 1 to my_object.Employee.Records.Count
    Debug.Print my_object.Employee.Records(x).ID
Next

会快得多:

For x = 1 to my_object.Employee.Records.Count
    With my_object.Employee.Records(x)
        Debug.Print .ID
    End With
Next

并且,正如@wqw所指出的那样,它可能会更快(取决于您需要访问多少属性),因为它提供了最少量的对象重新认证:

With my_object.Employee.Records
    For x = 1 to .Count
        Debug.Print Item(x).ID
    Next    
End With

试一试,你会看到差异。

答案 2 :(得分:1)

新答案只是为了发布代码。

请注意,无论是使用匿名With-cache还是显式引用变量(或过程参数),对象缓存并不总能达到预期效果。下面的DumpRS和DumpRSII都做同样的事情,打印RS中的所有值:

Option Explicit
'Add a reference to ADO 2.5 or later.

Private RS As ADODB.Recordset

Private Sub MakeRS()
    Dim I As Integer

    Set RS = New ADODB.Recordset
    With RS
        .CursorLocation = adUseClient
        .Fields.Append "SomeField", adInteger
        .Open
        For I = 1 To 10
            .AddNew Array(0), Array(I)
        Next
    End With
End Sub

Private Sub DumpRS()
    With RS.Fields(0)
        RS.MoveFirst
        Do Until RS.EOF
            Debug.Print .Value
            RS.MoveNext
        Loop
    End With
End Sub

Private Sub DumpRSII(ByVal Field As ADODB.Field)
    With RS
        .MoveFirst
        Do Until .EOF
            Debug.Print Field.Value
            .MoveNext
        Loop
    End With
End Sub

Private Sub Main()
    MakeRS
    DumpRS
    DumpRSII RS.Fields(0)
    RS.Close
End Sub

Field对象只是光标上的一个窗口。缓存Field对象可以显着提高重复行ADO操作的性能。

答案 3 :(得分:0)

我只使用第一个版本来设置属性值,比如C#中的初始化块。如果您正在调用方法等,请使用第二种形式。