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

发布于 2024-11-02 19:20:53 字数 374 浏览 0 评论 0原文

仔细阅读我正在维护的代码,我发现在某些地方使用了 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()

这两种形式之间有什么细微的区别吗?一般来说,我应该更喜欢哪一个?

(我个人的观点是,我选择第二个,因为在第一个筑巢两到三个之后,它开始让我头疼——这是一个充分的理由吗?)

Perusing the code I am maintaining, I see that in some places the With - End With construct is used...

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

and sometimes the more straightforward

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

Are there any subtle differences between these two forms? And in general, which should I prefer?

(My personal view is that I go for the second because after two or three nestings for the first it starts to make my head hurt - is that an adequate reason?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

又怨 2024-11-09 19:20:53

如果对象引用实际上是更复杂的表达式(例如属性 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 块,这实际上是个人喜好的问题。和你一样,我肯定会发现许多嵌套的 With 块令人困惑。这可能也是一个标志,表明该功能应该拆分为多个功能。

There is a difference if the object reference is actually a more complicated expression, like a property getter or the return value of a function.

Compare this:

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

Against the obviously incorrect:

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

The actual equivalent in this case would be to create a reference:

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

As to whether you should use With blocks, it is really a matter of personal preference. Like you, I would certainly find many nested With blocks confusing. It is probably also a sign that the function should be split into multiple functions.

好久不见√ 2024-11-09 19:20:53

贾斯汀是不正确的。 With...End With 构造不仅仅是语法上的糖果,它也是一个性能技巧。当您的对象路径包含多个点 (.) 时,性能提升非常明显,特别是在循环和/或处理类型(结构)时。

例如,这段代码:

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

尝试一下,您就会发现差异。

Justin is incorrect. With...End With construct is not just syntactic candy, it's also a performance trick. When you have an object path that includes several dots (.), the performance increase is pretty noticeable, particularly when looping and/or dealing with Types (structs).

For instance, this code:

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

will be much faster as:

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

and, as pointed out by @wqw, it will likely be even faster (depending on how many properties you need to access) like this since it offers the least amount of object re-qualification:

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

Give it a shot, you'll see the difference.

破晓 2024-11-09 19:20:53

新答案只是发布代码。

请注意,无论是使用匿名 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 操作的性能。

New answer just to post code.

Note that object caching doesn't always do what you expect whether using the anonymous With-cache or an explicit reference variable (or procedure argument). Both DumpRS and DumpRSII below do the same thing, printing all of the values in 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

The Field object is just a window on the cursor. Caching Field objects can improve the performance of repeated-by-row ADO operations significantly.

疏忽 2024-11-09 19:20:53

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

I would use the first version only for setting property values like an initialization block in C#. If you are calling methods etc., then use the second form.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文