2011-04-20 97 views
3

细读我维护的代码,我看到,在一些地方,With - End With结构用于...什么时候应该使用With-End With和什么时候应该在VB6中使用普通的对象引用?

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() 

是否有这两个之间的任何细微的差别形式?一般来说,我应该选择哪一个?

(我个人的看法是,我去的第二个,因为两个或三个嵌套它开始让我的头不疼后的第一个 - 是的充分理由?)

回答

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 

给它一枪,你会看到不同之处。

+0

更喜欢'With my_object.Employee.Records' outbound循环,然后在' – wqw 2011-04-21 06:30:18

+0

之内调试打印.Item(x).ID'你是说第一个还是第二个会更快? (对不起,我只是不确定是否“快得多”的意思是“比”快得多“,或者”如果变为“快得多)。如果第二个更快,那确实很有趣 - 你知道为什么它更快吗? – Justin 2011-04-21 12:32:50

+0

@Justin,第二个**更快**。 – AngryHacker 2011-04-21 17:14:30

0

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

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 

至于是否你应该使用块,这实际上是个人喜好的问题。像你一样,我肯定会发现许多嵌套块混淆。这也许是一个标志,该功能应该被分解为多个功能。

+1

我不买“筑巢不好”的说法。您可能会轻易声称嵌套If-blocks是您应该拆分该过程的标志。荒谬。缓存的匿名引用不会花费任何东西,而声明另一个引用变量则会计入您的模块和项目符号总数。这更多的是你如何理解语言的问题,并且新手们会更喜欢每次使用对象的超级限定。 – Bob77 2011-04-20 19:22:58

+0

@Bob - 就我个人而言,我会与许多嵌套的块(超过2或3,如OP所说)混淆。嵌套的if语句也是如此 - 它们一旦嵌套得太深,就会变得混乱,难以重构。 – Justin 2011-04-20 19:33:40

+0

@Bob - 很高兴知道参考变量可以反映出符号总数 - 我从未想过会有一个限制。快速搜索显示它约为32k个符号([source](http://msdn.microsoft.com/en-us/library/aa240819%28v=vs.60%29.aspx))。 – Justin 2011-04-20 19:35:48

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操作的性能。

相关问题