Jack said:
I was never aware of this. Thanks Dirk
FWIW, for me, a common use of static variable is to create a read-only
property without going through the expense of instantiating of the
object everytime.
Here's an example of what I commonly do when I need an ADO connection
object. In the project, I only need one connection object for the
application's lifetime, and I don't want to litter my code with orphaned
connection objects or worse, create more than one and have them step on
each other, raising bogus 'read/write conflict' or 'lock conflict' or
similar erros. Thus, I get my ADO connection from a read-only property:
Property Get Conn() As ADODB.Connection
Static con As ADODB.Connection
If con Is Nothing Then
Set con = New ADODB.Connection
'Other settings for the connections...
End If
Conn = con
End Property
With this procedure, I have hid my connection object to the procedure so
there's no need for a module-level variable to hold the connection (and
thus exposing it to other procedures in the same module... I may be able
to discipline myself to not use it but there is no guarantee I'll
remember to do so or that other programmer who replace me will
understand that it is not to be touched. Static, thus, helps with
documenting "Do not try to change this connection object outside of the
property procedure".
Furthermore, notice that I have a If/Then testing whether the static
variable has been instantiated and in case it's not, instantiate it.
This is useful in cases where the object may have been inadvertently
destroyed so the procedure self-heals and I always get a valid
connection object without need to be concerned that I've destroyed it
somewhere else or an error re-initialized it or whatever. It'll always
work when I need it and I won't have more than one connection object
(providing that my code consistently call this property instead of
creating its own connection object).
Note: I fudged a bit in the paragraph above previous paragraph -
Technically, static variable will not protect the connection object from
being modified when it has been called and placed in another variable
for the calling procedure, but that's generally OK because I usually
don't do that. Furthermore, I think the intention is more clear to other
programmers reading my code regarding my intention with the object.
Besides, the self-healing feature is really what make it useful.
If I really wanted to enforce all setting on an object, I could put the
connection settings outside the If/Then block so it always get set
everytime it's called but that would add a bit of overhead. YMMV.