Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

To NEW or not to NEW, that is the question... 12

Status
Not open for further replies.

zakman

Programmer
Aug 15, 2001
49
US
There has been some discussion in our workplace concerning the advantages/disadvantages of creating objects. We were analyzing these different methods, and there may be other ways also. What is your opinion on these, which is considered to be the 'best' method?

1. dim adoThing as New ADODB.Recordset

2. dim adoThing as ADODB.Recordset
...
set adoThing = new ADODB.Recordset

3. dim adoThing as ADODB.Recordset
...
set adoThing = CreateObject("ADODB.Recordset")

4. ?
 
Good question...

First let's determine what the differences are and then talk about why you would use one or the other.

When you do this:

Dim obj As New objType

you are defining obj implicitly.

When you do this:

Dim obj as objType
Set obj = New objType

you are defining obj explicitly.

When you use New in the Dim statement, the object will be created the first time the object is refererenced. For example

Dim objCustomer as New clsCustomer

objCustomer.FirstName = "Joe"

The setting of .FirstName does two things. First it creates the object if it doesn't exist, and secondly it sets the value of FirstName to "Joe". This is implicit object creation.

When you don't use the New statement in the Dim statement you have to EXPLICITYLY create the object like this, before you can use it:

Set objCustomer = New clsCustomer

Now lets look at this:

Dim objCustomer As clsCustomer

objCustomer.FirstName = "Joe"

The above code would generate an error 91, object or with block not set. Why? Because the object is not yet created. In order to make it work correctly you have to write it like this:

Dim objCustomer as clsCustomer

Set objCustomer = New clsCustomer
objCustomer.FirstName = "Joe"

Now it works just fine. Also note that you use the same syntax to destroy the object regardless of how it's created.

Set objCustomer = Nothing

To understand where and when to use one over the other, lets look at an example:

Dim objCustomer As New clsCustomer

objCustomer.FirstName = "Joe"
Debug.Print objCustomer.FirstName

Set objCustomer = Nothing

Debug.Pring objCustomer.FirstName

Before you read on, try to determine what the output of the above program would be for both debug.print statements. This is a question that I like to ask a VB Programmer during an interview.

If you said it generated an error, you weren't correct.

If you said it would print "Joe" and "" (empty string) you were right.

Now lets determine what's really happening... We're creating the object, then using it, then destroying it. Since we destroyed it, it probably meant we were done with it. HOWEVER.. there's another reference to it after we destroyed it. So it creates a new object, with all the properties blank, but doesn't give us an error or any warning as to what it did. It is for this reason that I DON'T LIKE IMPLICIT OBJECT CREATION!!! I feel that defining the New Keyword in the variable declaration is asking for trouble. Things like this can lurk in the code and drive you crazy. Now imagine the same program as above, but take the NEW keyword out of the variable declaration. If you run the program again, you'll get an error when you reference the FirstName property after the object was destroyed. In my opinion this is much better because it's probably telling you that you did something that you didn't really mean to do. If you let the object recreate itself, it's harder to find out why all your properties are blank and 0 or different, then if you find out that you're trying to use an object that's not created yet.

I use this as a rule of thumb. When you use an implied programming style it makes the code harder to understand, especially if you're the one looking at someone else's implied programming style of code.

When I see objCustomer.FirstName and there is no object created before it, I ask myself, "Is this really what they inteded to do?". If I see Set objCustomer = New clsCustomer then there's no doubt in my mind that the programmer EXPLICITLY wanted that to be there. Same thing for DIM statements at module levels.

If I said:

Option Explicit
Dim x As Integer

What is the intended scope? You don't know cause it's implied, unless you know the scope rules of the different types of modules. If it's a Class or a Form, the scope is Private, if it's in a module, the scope is public. It would be much better to say:

Option Explicit
Private x As Integer

That way I know the programmer specified the scope of the variable.

I tend to shy away from IMPLICIT programming just because it seems to be so vague. I try to explicitly state what I want to happen in the code.

As far as

Set objCustomer = New clsCustomer
vs.
Set objCustomer = CreateObject("MYDLL.clsCustomer")

I couldn't tell you which one is faster or better. I think it's just a matter of style. I believe it's two different ways to say the same thing.

Just my $2.50 worth.... Snaggs
tribesaddict@swbell.net
Life can only be understood backwards; but it must be lived forwards.
 
Snaggs,

That was a very good and complete description of the issue and was something I personally hadn't given alot of thought to.
 
If you use
Code:
Dim X As New ObjType
, VB will create the object the first time you reference it. This will cause the VB runtime to check if the object has been initialised on each reference to it and initialise it if not.

If you use
Code:
Dim X As ObjType
Set X = New ObjType
VB knows exactly when to create the control and will not perform checking on each reference.

Common sense says that it is more efficient to not have the VB runtime constantly checking if the object has been initialised each time you use it.

I prefer to be explicit in all my code - I know exactly when I am creating objects and always dispose of them. So as soon as I type the "Set X = New ObjType" I then type the "Set X = Nothing" to dispose of the object explicitly.

Don't leave VB to do your cleaning up for you - it's not exactly one of its strengths.

Snaggs gets a star from me though - good answer!
 
personally, i think there are different 'best' methods for different situations.

for example you could use advantage of the 'Obj as New ObjType' when you are writing functions/subs where the object would only be local to the function/sub, that way it would be destroyed when the sub exits. This is handy for those simple functions. if the function grows to become complicated i tend to drop the New keyword to improve readability and decrease chances of recreation of the object.

for global objects i tend to 'As New' (unless with withevents) - if i know the object will only be used once throughout the whole class (like a global FileSystem Object), thus again it would be destroyed when the class looses scope(when the program ends). Also I use 'As New' for global arrays of Objects, then i use Erase which will set them all to Nothing.

i hardly use CreateObject(), unless the Variable is of type Object/Variant and i have to use late-binding for some reason.

the biggest problem i have with 'As New' is that you cant compare the Object to Nothing, consider:

private Obj as New ObjType
private iCount as long

private function GetMyObj() as ObjType
dim oRet as New ObjType
if iCount < 3 then
oRet.Count = iCount
set GetMyObj = oRet
else
set GetMyObj = Nothing
endif
end function

private sub Command1_Click()
iCount = 3
set obj = GetMyObj
if obj is nothing then
msgbox &quot;Count is greater than 3&quot;
endif
end sub


The act of comparing 'obj is nothing' actually creates an instance of the object because it is dimmed as New.

Incidentially Forms are automatically dimmed 'As New' in VB, this really gets me because i tend to code initialisation code in the Form_Load event. Then, if i want to check that a form has been unloaded I cant do

if frmMain is nothing

because it will load the form again. Thus i end up Explicitally Dimmimg the Form :

Dim FormMain as frmMain
...
set FormMain = new frmMain

...
if FormMain is nothing then
msgbox &quot;Sorry you have closed this form one too many times&quot; ....
endif .

 
Snaggs - excellent - I would have failed your interview :(
But is it the same in .net do you know?

I am migrating to .net at the moment and subtle differences like this can drive you mad.

In all the .net stuff I've read, implicit stuff is all over the place

eg
dim ThisCustomer as clsCustomer = new clsCustomer

and you can even do

dim x as integer = 10

Mark
 
Mark,

I haven't had a chance to work with .NET yet. Try the little program I mentioned above in .NET and see what happens. That should answer your question. Post back here so others will know what you found out.

I'm looking forward to moving to .NET, I just have some stuff to finish up in VB6 before I can make the switch. Snaggs
tribesaddict@swbell.net
Life can only be understood backwards; but it must be lived forwards.
 
Snaggs
Sorry for the delay
You will really like .net
These three ways of creating an object

Dim oJoe as Joe = new Joe()

Dim oJoe as new Joe()

Dim oJoe as Joe
oJoe = new Joe

All do the same thing - explicit creation - they all raise an error if you try to assign a property after you've said

oJoe = Nothing

Note that the set keyword is not supported - this is because .net does not support default properties, so there can be no ambiguity when you say

oJoe = oBob 'this is an object assignment in .net - in VB6 this would copy the default property from Bob to Joe.

I quite like this actually, and the IDE lets you type 'set' - it just takes it out for you after you move off the line.

Mark
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top