具有在VB.NET中使用vs结束

具有在VB.NET中使用vs结束,vb.net,scope,idisposable,using-statement,with-statement,Vb.net,Scope,Idisposable,Using Statement,With Statement,我刚刚发现,与C#一样,VB.NET也有using关键字 直到现在,我还以为它没有(我真傻,我知道…),而是做了这样的事情: With New OleDbConnection(MyConnectionString) ' Do stuff End With 与使用像这样的语句进行相比,这意味着什么 Using cn as New OleDBConnection(MyConnectionString) With cn ' Do stuff with cn En

我刚刚发现,与C#一样,VB.NET也有
using
关键字

直到现在,我还以为它没有(我真傻,我知道…),而是做了这样的事情:

With New OleDbConnection(MyConnectionString)
   ' Do stuff
End With
与使用像这样的
语句进行
相比,这意味着什么

Using cn as New OleDBConnection(MyConnectionString)
    With cn
        ' Do stuff with cn
    End With
End using
更新:

我应该补充一点,我熟悉
using
语句的功能,因为它在退出构造时处理对象

然而,据我所知,带有New…
构造将让对象在对象超出范围时将其标记为准备进行垃圾收集

所以我的问题是,唯一的区别是,使用
时,我会立即释放内存,而使用
时,只要GC愿意,就会释放内存?还是我错过了更大的东西

是否存在任何最佳实践影响?我应该用新的MyDisposableObject()重写我使用的所有代码吗。。。使用o作为新的MyDisposableObject()
作为
结束

通过使用With…End With,可以对指定的对象执行一系列语句,而无需多次指定对象的名称

Using块的行为类似于Try…Finally构造,其中Try块使用资源,Finally块处理资源

托管资源由垃圾回收器处理,无需您进行任何额外编码。 您不需要使用语句。
有时代码需要非托管资源。你有责任处理它们。使用块可确保在代码完成时调用对象上的Dispose方法。

区别在于
与…End一起使用

Using cn as New OleDBConnection(MyConnectionString)
    With cn
        ' Do stuff with cn
    End With
End using
With New OleDbConnection(MyConnectionString)
    ' Do stuff
End With
超出范围时自动调用
cn.Dispose()
使用结束)。但是在
中有新的…结尾

Using cn as New OleDBConnection(MyConnectionString)
    With cn
        ' Do stuff with cn
    End With
End using
With New OleDbConnection(MyConnectionString)
    ' Do stuff
End With
.Dispose()未显式调用

同样,使用命名对象,您可以在即时窗口中创建手表和
?cn
。对于未命名对象,您不能使用语句/块。


然而,据我所知,新的。。。构造将让对象在对象超出范围时将其标记为已准备好进行垃圾收集

这是真的,也不是真的。从某种意义上说,所有对象都被“标记”(纯粹主义者可能会质疑这个术语,但细节并不相关)为超出范围的垃圾收集做好了准备。但是从这个意义上讲,这也不是完全正确的,因为对于这种行为,
With
关键字没有什么特别之处。当对象超出范围时,它有资格进行垃圾收集。时期这对于方法级范围和块级范围都是正确的(例如,使用
使用
等)

但这并不是您将
一起使用的原因。原因是它允许您在深度嵌套的对象上按顺序设置多个属性。换句话说,假设您有一个对象,要在其上设置一组属性,并通过以下方式访问它:
MyClass.MemberClass.AnotherMemberClass.Items(0)
。看到那些点了吗?从理论上讲,编写代码的效率可能会变得很低,因为每次设置属性时,代码都必须一遍又一遍地通过一系列点才能访问完全相同的对象。如果你知道C或C++(或者任何其他有指针的语言),你可以把每个点都看作是指针引用。
With
语句基本上只执行一次所有间接操作,并允许您直接对存储在临时变量中的对象设置属性

也许一些代码可以让事情变得更清楚。每当你看到一个点,思考可能会很慢

假设您从以下代码开始,从深度嵌套的
Items
集合中检索对象1,并在其上设置多个属性。看看我们需要检索多少次对象,即使每次都是同一个对象

MyClass.MemberClass.AnotherMemberClass.Items(0).Color   = Blue
MyClass.MemberClass.AnotherMemberClass.Items(0).Width   = 10
MyClass.MemberClass.AnotherMemberClass.Items(0).Height  = 5
MyClass.MemberClass.AnotherMemberClass.Items(0).Shape   = Circle
MyClass.MemberClass.AnotherMemberClass.Items(0).Texture = Shiny
MyClass.MemberClass.AnotherMemberClass.Items(0).Volume  = Loud
现在,我们将该代码修改为使用带有
块的

With MyClass.MemberClass.AnotherMemberClass.Items(0)
    .Color   = Blue
    .Width   = 10
    .Height  = 5
    .Shape   = Circle
    .Texture = Shiny
    .Volume  = Loud
End With
Try
    ' [1: Create/acquire the object]
    Dim g As Graphics = myForm.CreateGraphics()
    
    ' [2: Use the object]
    g.DrawLine(Pens.Blue, 10, 10, 100, 100)
    ' ... etc.
End Try
Finally
    ' [3: Ensure that the object gets disposed, no matter what!]
    g.Dispose()
End Finally
但是,此处的效果与以下代码相同:

Dim tempObj As MyObject = MyClass.MemberClass.AnotherMemberClass.Items(0)
tempObj.Color   = Blue
tempObj.Width   = 10
tempObj.Height  = 5
tempObj.Shape   = Circle
tempObj.Texture = Shiny
tempObj.Volume  = Loud
当然,您不会引入新的作用域,因此在更高级别的作用域结束之前,
tempObj
不会超出作用域(因此有资格进行垃圾收集),但这几乎不是一个相关的问题。性能增益(如果有)附加到后两个代码段

如今,将
块一起使用的真正好处不是性能,而是可读性。有关使用
、可能的性能改进、风格建议等的更多想法,请参阅

与新的
? 将
New
关键字添加到
With
语句中与我们刚才讨论的效果完全相同(创建一个局部临时变量来保存对象),只是它几乎完全没有意义。如果需要使用
New
创建一个对象,那么最好声明一个变量来保存它。稍后您可能需要对该对象执行某些操作,例如将其传递给另一个方法,但不能在带有
块的
中执行此操作

使用New
的唯一目的似乎是,它允许您避免显式的变量声明,而不是让编译器隐式地进行声明。说我疯了,但我看不出这有什么好处

事实上,我可以说,我从来没有见过任何实际的代码使用这种语法。我能在谷歌上找到的唯一东西是(无论如何,
Call
是一个更好的选择)

使用
语句/块 与使用
不同,
使用