Fog Creek Software
Discussion Board




What is actually wrong with VBs As New?

It is common knowledge that VBs as new declaration should not be used.

ie.  You should always use

Dim A as Object:Set A = New Object

and never

Dim A as New Object

However, I don't actually know why.  I think it has something to do with threading, but cannot be certain.

I searched on Google but couldn't find anything.  The best find was this MSDN article, which seems to indicate that there is no differece between New and As New.

msdn.microsoft.com/library/en-us/vbcon98/html/ vbconhowobjectcreationworksinvbcomponents.asp

Could somebody please clarify why using As New is a bad idea, or am I victim of an Urban Myth?

Thanks.

Ged Byrne
Thursday, June 05, 2003

Because even after you do
SET A = nothing
you will STILL be able to reference A and get a NEW object after that.

As long as you are in scope you will always get a new object. That's WACKED !

Bling bling !

Application Specialist
Thursday, June 05, 2003

Also, when does the Class_Initialize event fire?

John Topley (www.johntopley.com)
Thursday, June 05, 2003

Objects can be "created" in VB in either of these ways:

(1) Dim objX As New ADODB.Connection

(2) Dim objY As ADODB.Connection: Set objY = New ADODB.Connection

With the first approach, the object is not actually created until it is referenced in some way (any way). For example, when you do:

Dim objX As New ADODB.Connection
MsgBox objX.Version

- the object is created when "objX.Version" is executed. Behind the scenes, it's a little more complicated because the VB interpreter wraps every reference to an object that is Dim'ed "As New" with code that checks whether the object already exists and creates the object if it doesn't - and this causes a very slight decrease in performance (issue #1).

However, note that I said "any reference" to the object will create it, so a seemingly logical statement like:
If objX Is Nothing Then
will also create the object (even if it has never been used yet, and even if the immediately previous statement set it to "Nothing") and therefore the object (Dim'ed "As New")cannot be "Nothing" in this "If" condition. A reference to the object variable in any statement will create the object if it doesn't already exist.

Normally, you should use the second approach for creating objects in VB, and also you normally don't call the "Set" statement until just before you need to use the object - for example:
Dim objY As ADODB.Connection
[... several statements to check input parameters, construct values, etc.]
Set objY = New ADODB.Connection
[Call a method on the object]
[Close (if appropriate) the object and set it to Nothing]
[...]


Note - if the object you are creating is running in MTS (or COM+) then you should not use the "New" operator to create the object at all, but use the "ObjectContext.CreateInstance" method (or the "CreateObject" method if you are sure you will only be using COM+) - but this is a separate topic.

Philip Dickerson
Thursday, June 05, 2003

Just tried some sample code and your right - it is quite mad!

Ged Byrne
Thursday, June 05, 2003

Philip is correct, however, aware as I am of the technical implications, I avoid the 'As New' construct because I just don't like the look of it in my code ;)

Foolish consistency, or what?

Justin
Thursday, June 05, 2003

Dim thread as old  :)

http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=24747&ixReplies=26

I'm surprised you missed this one actually Ged

Stephen Jones
Thursday, June 05, 2003

I'm surprised too.  I must have been doing some real work that day.

Ged Byrne
Thursday, June 05, 2003

Dim X as New Widget does this everything time you access the variable

If X is nothing then
  Set X = New Widget
End if
<Do Code>

So

X.Alpha = "Hello"
X.Beta = "World"
X.Gamma = "Today"

is executed as

If X is nothing then
  Set X = New Widget
End if
X.Alpha = "Hello"
If X is nothing then
  Set X = New Widget
End if
X.Beta = "World"
If X is nothing then
  Set X = New Widget
End if
X.Gamma = "Today"

this happens behind the scene and can slow down execution speed.

Doing

Dim X as Widget
Set X = New Widget

avoids all this.

Robert Conley
Thursday, June 05, 2003

>Also, when does the Class_Initialize event fire?
That hits the major reason on the head.

Yes, the real reason here is you can control in code better when the initialize event fires. This might be your own custom class object, or any library/com object you use.

Albert D. Kallal
Thursday, June 05, 2003

So why doesn't the compiler just optimize all instances of "As New" into the more efficient format?

Nate Silva
Thursday, June 05, 2003

Posted too soon... Albert says it's so you can control when the Initialize event fires. It seems a high price to pay that the more intuitive "As New" syntax would invoke an "If X Is Nothing" test on every access to the object -- just to give you a little more control over the Intialize event. Like the cure that's worse than the disease.

Nate Silva
Thursday, June 05, 2003

Actually, what VB does is wait until you actually use the object, AND THEN the initialize event fires. So, using the new keyword is not really that bad at all. It is just that you are more explicit in your code as to where the actual object gets initialized (event) when you drop the new keyword.

For example:

If you are just reading some code like:

MyTour.TourId = 123

Now, looking at the above code, is the initialize event going to fire? You don’t know. If did not use the new keyword, then the programmer would have had to write:

Set MyTour = new clsRides
MyTour.TourId = 123

So, now the above code is clear to you that the object was just initialized.

So, Nate’s suggestion that the compiler should take care of this is in fact what kind of happens. Well, ok, the first time you use the object anywhere in code, then the initialize event fires...I not sure if the compiler actually does this, but in effect it is the same result.

If we need the initialize event to fire, and not yet use any methods, or set any properties of the object, then dropping the new keyword is better.

We can use:

Set MyTour = new clsRides

So, no new keyword means we can just initialize the object without actually using a property or method of the object.

It is wrong of me to state that the initialize event fires when the new keyword is used in "dim". That does NOT happen. The initialize event fires on the first use of the object anywhere in the code. One might even argue that this is BETTER then having to force the initialize event manually. If you have  a lot of code, then you actually might prefer that the first reference to the object in code runs the initialize event.

However, trying to debug, and figure out when that first use occurs can be very hard. So, it is question of clarity, not performance. Use of new key word in a dim is not great, but it is not that bad either...

Albert D. Kallal
Edmonton, Alberta Canada
kallal@msn.com
http://www.attcanada.net/~kallal.msn

Albert D. Kallal
Friday, June 06, 2003

Albert,

You stated:

The initialize event fires on the first use of the object anywhere in the code.

This is not strictly speaking correct. A more correct statement would be:

Whenever the object variable is referenced, if the object variable Is Nothing then a new object is created and assigned to the object variable (firing the Initialize event). if the object variable is not Nothing then nothing occurs (ie the object is not recreated, and the Initialize event won't fire).

While your statement and mine are much the same, mine is more explicit, in that it explains what will happen if you set the object variable to Nothing and then reference it again.

Matthew
Monday, June 09, 2003

*  Recent Topics

*  Fog Creek Home