有几个关键的区别。你应该绝对偏好第二个 Dim/Set
方法。
原因1 - 用 As New
,对象只在该对象的一个属性或方法被调用时创建,但是看下这个例子,在将对象设置为 Nothing
,然后调用一个属性/方法会导致对象重新实例化:
Sub ShortcutInstantiation()
Dim x As New Collection
x.Add "FOO", "BAR"
Set x = Nothing
'This line implicitly recreates a new Collection
Debug.Print x.Count
Debug.Print x Is Nothing 'Prints False
End Sub
Sub SafeInstantiation()
Dim x As Collection
Set x = New Collection
x.Add "FOO", "BAR"
Set x = Nothing
'Throws error because x is nothing
Debug.Print x.Count
End Sub
原因2 使用As New
方式较慢,因为VBA需要在每次属性或方法调用之前检查对象是否已被实例化。
看一下这个伪代码,就能明白VBA在幕后做了什么:
Sub NotSoShortcutInstantiation()
Dim x As New Collection
If x Is Nothing Then Set x = New Collection
x.Add "FOO", "BAR"
If x Is Nothing Then Set x = New Collection
x.Add "FIZZ", "BUZZ"
If x Is Nothing Then Set x = New Collection
x.Add "CAR", "DOOR"
If x Is Nothing Then Set x = New Collection
Debug.Print x.Count
End Sub
原因 3 如果您的对象构造函数在您期望之后执行某些操作,而不是在显式实例化时执行操作,则可能存在关键时间差:
比较以下代码的结果:
Sub InstantiationTiming()
Dim foo As String
Dim x As New Class1
Debug.Print Format(Now(), "hh:mm:ss") & " x should be ready"
foo = x.foo
Dim y As Class1
Set y = New Class1
Debug.Print Format(Now(), "hh:mm:ss") & " y should be ready"
foo = y.foo
End Sub
As New
方法输出:
06:36:57 x should be ready
06:36:57 Class Initialized
Set y = New
方法会输出:
06:36:57 Class Initialized
06:36:57 y should be ready
as new
和直接创建对象的区别在于,使用as new
延迟对象的创建,直到第一次(以及之后所有)跨引用变量调用时才创建。具体原因可以参考这个链接:为什么不在声明时实例化对象? - Alex K.