467,876 Members | 1,072 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,876 developers. It's quick & easy.

Access member variable directly or through property within the class it is defined?


(Slightly religious question):

Suppose I have the following class:

---snip---
Public Class MyClass
Private _MyVariable As Integer

Public Property MyVariable() As Integer
Get
Return Me._MyVariable
End Get
Set(ByVal value As Integer)
'(some value checking going on here)
Me._MyVariable = value
End Set
End Property

Private Sub MyMethod1
_MyVariable = 0
End Sub

Private Sub MyMethod2
MyVariable = 0
End Sub

End Class
---snip---

Is there a recommended best practice (class library design
guidelines?) for accessing _MyVariable?

MyMethod1 takes the direct route, thereby bypassing any
value checking and side effects in the property setter.

MyMethod2 goes through the property setter, which has
the benefit of value checking/side effects, but might be
overkill considering the performance hit incurred by the
extra function call, especially if the values assigned are
known to be valid.

Still, if the priority is *maintainability*, wouldn't it be best only
to use the direct access in the constructor only and the
property setter in all other cases? To avoid multiple side
effects as a result of setting multiple properties at once
(e.g. if the class is a graphical control), would the best
practice be to disable all updates, set multiple properties,
then enable updates again, in order to use property setters
all the time internally?

What do you do?

/JB

Feb 22 '06 #1
  • viewed: 2177
Share:
37 Replies
CMM
IMHO, I think it's perfectly fine for a Class to "internally" set its
private variables without going through their Accessors. The class (you as
the developer) should know when this makes sense and when it doesn't. For
instance, when you want PropertyChanged events to be raised with
databound-aware classes (yes, even regular ol' classes support this) then
you'll probably want to change properties via their Accessors.

It should be noted that there is practically 0% performance impact by going
through the Accessors.... however, for the situations where Property
Accessors actually do WORK, then for the sake of consistency and
maintainability (and maybe performance)... sometimes implementing a
WindowsForms-like 'SuspendLayout' - Modify Lots of Properties -
'ResumeLayout' is nice and elegant even INSIDE the class. This is
situation-specific and definately not a "rule."

In short... it's up to you.

P.S. Now, whether you should be using PascalCase and underscores for private
variables is a totally different matter. That IS a religious question. ;-)

P.P.S. When accessing *Properties Accessors* internally it helps
maintainability to do so using "Me." This is a fairly common coding standard
(unfortunately not so much in the VB world). The rule doesn't really apply
to the variables themselves or to Methods... just Properties. If you use
this practice for awhile, you'll see why it makes sense.

--
-C. Moya
www.cmoya.com
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:vo********************************@4ax.com...

(Slightly religious question):

Suppose I have the following class:

---snip---
Public Class MyClass
Private _MyVariable As Integer

Public Property MyVariable() As Integer
Get
Return Me._MyVariable
End Get
Set(ByVal value As Integer)
'(some value checking going on here)
Me._MyVariable = value
End Set
End Property

Private Sub MyMethod1
_MyVariable = 0
End Sub

Private Sub MyMethod2
MyVariable = 0
End Sub

End Class
---snip---

Is there a recommended best practice (class library design
guidelines?) for accessing _MyVariable?

MyMethod1 takes the direct route, thereby bypassing any
value checking and side effects in the property setter.

MyMethod2 goes through the property setter, which has
the benefit of value checking/side effects, but might be
overkill considering the performance hit incurred by the
extra function call, especially if the values assigned are
known to be valid.

Still, if the priority is *maintainability*, wouldn't it be best only
to use the direct access in the constructor only and the
property setter in all other cases? To avoid multiple side
effects as a result of setting multiple properties at once
(e.g. if the class is a graphical control), would the best
practice be to disable all updates, set multiple properties,
then enable updates again, in order to use property setters
all the time internally?

What do you do?

/JB

Feb 22 '06 #2
Joergen,

Maybe can the only problem be that you come in trouble in version 2005
because the start with an underscore for a variable is not always CLS
compliant.

See a long current thread in this newsgroup from someone who was in trouble
with that. I have only touched it slightly.

In fact are your methods 1 and 2 without sense. And therefore I would
absolute not implement them at all.

Cor
Feb 22 '06 #3
"Cor Ligthert [MVP]" <no************@planet.nl> schrieb:
Maybe can the only problem be that you come in trouble in version 2005
because the start with an underscore for a variable is not always CLS
compliant.

See a long current thread in this newsgroup from someone who was in
trouble with that. I have only touched it slightly.


Well, but this does not apply to private variables.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #4
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb:
---snip---
Public Class MyClass
Private _MyVariable As Integer

Public Property MyVariable() As Integer
Get
Return Me._MyVariable
End Get
Set(ByVal value As Integer)
'(some value checking going on here)
Me._MyVariable = value
End Set
End Property

Private Sub MyMethod1
_MyVariable = 0
End Sub

Private Sub MyMethod2
MyVariable = 0
End Sub

End Class
---snip---

Is there a recommended best practice (class library design
guidelines?) for accessing _MyVariable?
I do not know if there is a recommendation, but I recomment to call the
accessor instead of accessing the private variable even in the class. The
advantage of doing that is that validation code gets executed and that it's
guaranteed that the private variable never holds an invalid value. This
prevents errors from occuring in algorithms and methods relying on the
property's value. By accessing the property duplicated range-checking code
can be removed and put into the property's 'Set' part only.

The runtime overhead for accessing the property instead of the variable
should be minimal given the JITter could inline the property access in some
cases.
Still, if the priority is *maintainability*, wouldn't it be best only
to use the direct access in the constructor only and the
property setter in all other cases?


I /always/ set the property value through the property.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #5

Underscores or no underscores and whether the methods
are useful for anything is besides the point. I am aware that
I need to re-read some guidelines for coding style. Some other
time.

The question was about best practices for accessing member
variables. The sample was written as concisely as possible to
illustrate the differences.

/JB

On Wed, 22 Feb 2006 11:14:51 +0100, "Cor Ligthert [MVP]"
<no************@planet.nl> wrote:
Joergen,

Maybe can the only problem be that you come in trouble in version 2005
because the start with an underscore for a variable is not always CLS
compliant.

See a long current thread in this newsgroup from someone who was in trouble
with that. I have only touched it slightly.

In fact are your methods 1 and 2 without sense. And therefore I would
absolute not implement them at all.

Cor


Feb 22 '06 #6
Still, if the priority is *maintainability*, wouldn't it be best only
to use the direct access in the constructor only and the
property setter in all other cases?


I /always/ set the property value through the property.


The constructor is *the* one place where I normally would want
to initialize all the members directly, without any checks or
side effects, but come to think of it ... good point you made there.

/JB

Feb 22 '06 #7
>> Maybe can the only problem be that you come in trouble in version 2005
because the start with an underscore for a variable is not always CLS
compliant.

See a long current thread in this newsgroup from someone who was in
trouble with that. I have only touched it slightly.


Well, but this does not apply to private variables.

--


So I wrote it correct?

:-)

Cor
Feb 22 '06 #8
CMM
I don't think there's much controversy in any development community
concerning this. The only general rule is that Accessors (C++ terminology)
must be used by other classes. Inside the class, you're free to do as you
wish... as long as its consistent. I agree with the others here that it's
"good" if you use the Accessors internally.....

..... though I myself don't care much for it. I use it only when it makes
sense to do so. Consistency is the Golden Rule. If you decide to *mainly*
access the variables directly, then only use the Accessors when you want to
trigger whatever work they do (validation, etc). If you decide to *mainly*
use Accessors, then only use the member variables for a darn good reason.
That way it becomes instantly clear to anyone maintaining your code what
your intentions were in a particular line of code.... "oh I see, he's
accessing the variable on purpose to sidestep the validation in this special
case."

P.S. Yes, I know this is slightly OT... but, one thing I would stress again
is using Me (for Properties). This is a pretty strict standard in the
development world (even though not many of us VB folks practice it... to
our detriment).

--
-C. Moya
www.cmoya.com

"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:2g********************************@4ax.com...
Still, if the priority is *maintainability*, wouldn't it be best only
to use the direct access in the constructor only and the
property setter in all other cases?


I /always/ set the property value through the property.


The constructor is *the* one place where I normally would want
to initialize all the members directly, without any checks or
side effects, but come to think of it ... good point you made there.

/JB

Feb 22 '06 #9
>.... though I myself don't care much for it. I use it only when it makes
sense to do so. Consistency is the Golden Rule. If you decide to *mainly*
Yes, Consistency is the key word, and since I am just starting a major
new project, I was looking for some "official" guidelines, e.g. FxCop,
Design Guidelines for Class Library Developers, SSW rules
(http://ssw.com.au/SSW/Standards/Default.aspx),
and yes, general recommendations from this group (or links to more
guidelines).
P.S. Yes, I know this is slightly OT... but, one thing I would stress again
is using Me (for Properties). This is a pretty strict standard in the
development world (even though not many of us VB folks practice it... to
our detriment).


The examples in Microsoft's own guidelines document use

m_myVariable

i.e. camel Casing for fields, and accessed without the Me
keyword (I am talking about the VB examples), but the framework
itself just uses camel Casing, without the m_ prefix.

So yes I agree, choose and stick with the choice.

I suppose prefixing the private fields with "m_" is the best approach:
If this is used consistently, there is never any doubt whether the
field is accessed directly or through the accessor. I like the prefix
approach (whether it is "_" or "m_") as it allows me to use the "same"
name for the field as well as the accessor. Visually, using "Me." is
a good argument if just using the "_" prefix, but might be overkill
if using the "m_" prefix(?) Hm ... I cannot use the same
name and let the scope rules determine what is what, i.e. look
at CheckBox.CheckState in the framework:

Private checkState As CheckState
Public Property CheckState As CheckState
Get
Return Me.checkState
End Get
...
End Property

Such code is for C#-programmers with their case-sensitivity.

....

Actually ... re-reading the Microsoft guidelines, they talk a lot
about how the classes should look externally, but no naming
conventions (that I can find) for private fields. Some examples
use the "m_" prefix, others postfix their fields with "Value"
(e.g. xValue for a property named X).

Only consistent thing is the use of camel Casing.

So I guess I am down to "Me._myVariable" or "m_myVariable".

/JB

Feb 22 '06 #10
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb:
Still, if the priority is *maintainability*, wouldn't it be best only
to use the direct access in the constructor only and the
property setter in all other cases?


I /always/ set the property value through the property.


The constructor is *the* one place where I normally would want
to initialize all the members directly, without any checks or
side effects, but come to think of it ... good point you made there.


I am wondering why you would bypass validation there. Especially if
assigning property values through parameters of the constructor I'd
recommend to use the accessor:

\\\
Private m_Age As Integer

Public Sub New(ByVal Age As String)
Me.Age = Age
End Sub

Public Property Age() As Integer
Get
Return m_Age
End Get
Set(ByVal Value As Integer)
If Value <= 0 Then
Throw New ArgumentException(...)
Else
m_Age = Value
End If
End Set
End Property
///

I'd even call the accessor if I only assign a constant value because
validation criteria may change over time.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #11
"CMM" <cm*@nospam.com> schrieb:
I don't think there's much controversy in any development community
concerning this. The only general rule is that Accessors (C++ terminology)
must be used by other classes. Inside the class, you're free to do as you
wish... as long as its consistent. I agree with the others here that it's
"good" if you use the Accessors internally.....
ACK.
.... though I myself don't care much for it. I use it only when it makes
sense to do so. Consistency is the Golden Rule.
I don't think consistency is the Golden Rule. Imagine a class having a
property 'Age As Integer' and 'Name As String'. While validating a value
assigned to 'Age' definitely makes sense and can help to avoid bugs in the
code, it will never be necessary to perform validaton on a person's name,
which can be an arbitrary string.
If you decide to *mainly* access the variables directly, then only use the
Accessors when you want to trigger whatever work they do (validation,
etc). If you decide to *mainly* use Accessors, then only use the member
variables for a darn good reason. That way it becomes instantly clear to
anyone maintaining your code what your intentions were in a particular
line of code.... "oh I see, he's accessing the variable on purpose to
sidestep the validation in this special case."


Could you think of a real-world sample where sidestepping the validation
would make sense?

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #12
CMM
I meant Me is used with Properties (Me.PropertyX = someValue). For member
variables you don't need to because usually their camelCase and/or
scope_notation ("m_" or "_" which is also not required... though camelCase
is) is enough.

--
-C. Moya
www.cmoya.com
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:ps********************************@4ax.com...
.... though I myself don't care much for it. I use it only when it makes
sense to do so. Consistency is the Golden Rule. If you decide to *mainly*


Yes, Consistency is the key word, and since I am just starting a major
new project, I was looking for some "official" guidelines, e.g. FxCop,
Design Guidelines for Class Library Developers, SSW rules
(http://ssw.com.au/SSW/Standards/Default.aspx),
and yes, general recommendations from this group (or links to more
guidelines).
P.S. Yes, I know this is slightly OT... but, one thing I would stress
again
is using Me (for Properties). This is a pretty strict standard in the
development world (even though not many of us VB folks practice it... to
our detriment).


The examples in Microsoft's own guidelines document use

m_myVariable

i.e. camel Casing for fields, and accessed without the Me
keyword (I am talking about the VB examples), but the framework
itself just uses camel Casing, without the m_ prefix.

So yes I agree, choose and stick with the choice.

I suppose prefixing the private fields with "m_" is the best approach:
If this is used consistently, there is never any doubt whether the
field is accessed directly or through the accessor. I like the prefix
approach (whether it is "_" or "m_") as it allows me to use the "same"
name for the field as well as the accessor. Visually, using "Me." is
a good argument if just using the "_" prefix, but might be overkill
if using the "m_" prefix(?) Hm ... I cannot use the same
name and let the scope rules determine what is what, i.e. look
at CheckBox.CheckState in the framework:

Private checkState As CheckState
Public Property CheckState As CheckState
Get
Return Me.checkState
End Get
...
End Property

Such code is for C#-programmers with their case-sensitivity.

...

Actually ... re-reading the Microsoft guidelines, they talk a lot
about how the classes should look externally, but no naming
conventions (that I can find) for private fields. Some examples
use the "m_" prefix, others postfix their fields with "Value"
(e.g. xValue for a property named X).

Only consistent thing is the use of camel Casing.

So I guess I am down to "Me._myVariable" or "m_myVariable".

/JB

Feb 22 '06 #13
CMM
Sure:
1) The property is ReadOnly... like is often the case when you expose
collections or another complex object. You usually do this when you want to
maintain a particular instance of an object for whatever reason, allow
external classes to manipulate but not "switch" the object, but, inside the
class you should be able to do whatever you want with the object.
2) The property has an "interpreted" fallback value given to the outside
world (If value = 0 Return -1)... but internally it is not useful to the
class.
3) Setting the property would cause an event to trigger or other code to
execute that is not useful to the class. Granted, there are more elegant
ways to do this (like the Form SuspendLayout, ResumeLayout example I gave in
another post).

I guess the assumption is that the class should know not to give a private
member an "invalid" value that would otherwise not be possible using the
Accessor.... and if it does do so, it's doing it *knowingly.*

Furthermore, it depends on what the class *does* IMHO, a "Property Accesor
Only" class might work well for regular ol' entity classes that represent
"data" (like a Person class) but not so much for a Custom Control, Form, or
other "action" oriented class that does more than just house information.

--
-C. Moya
www.cmoya.com
"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:%2***************@tk2msftngp13.phx.gbl...
"CMM" <cm*@nospam.com> schrieb:
I don't think there's much controversy in any development community
concerning this. The only general rule is that Accessors (C++ terminology)
must be used by other classes. Inside the class, you're free to do as you
wish... as long as its consistent. I agree with the others here that it's
"good" if you use the Accessors internally.....


ACK.
.... though I myself don't care much for it. I use it only when it makes
sense to do so. Consistency is the Golden Rule.


I don't think consistency is the Golden Rule. Imagine a class having a
property 'Age As Integer' and 'Name As String'. While validating a value
assigned to 'Age' definitely makes sense and can help to avoid bugs in the
code, it will never be necessary to perform validaton on a person's name,
which can be an arbitrary string.
If you decide to *mainly* access the variables directly, then only use
the Accessors when you want to trigger whatever work they do (validation,
etc). If you decide to *mainly* use Accessors, then only use the member
variables for a darn good reason. That way it becomes instantly clear to
anyone maintaining your code what your intentions were in a particular
line of code.... "oh I see, he's accessing the variable on purpose to
sidestep the validation in this special case."


Could you think of a real-world sample where sidestepping the validation
would make sense?

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>


Feb 22 '06 #14
"CMM" <cm*@nospam.com> schrieb:
1) The property is ReadOnly... like is often the case when you expose
collections or another complex object. You usually do this when you want
to maintain a particular instance of an object for whatever reason, allow
external classes to manipulate but not "switch" the object, but, inside
the class you should be able to do whatever you want with the object.


VB 2005 supports different levels of visibility for 'Get' and 'Set'.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #15
CMM
As Johnny Carson used to say... "I did not know that."
:-)

--
-C. Moya
www.cmoya.com
"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:%2******************@TK2MSFTNGP14.phx.gbl...
"CMM" <cm*@nospam.com> schrieb:
1) The property is ReadOnly... like is often the case when you expose
collections or another complex object. You usually do this when you want
to maintain a particular instance of an object for whatever reason, allow
external classes to manipulate but not "switch" the object, but, inside
the class you should be able to do whatever you want with the object.


VB 2005 supports different levels of visibility for 'Get' and 'Set'.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #16
On Wed, 22 Feb 2006 20:10:11 +0100, "Herfried K. Wagner [MVP]"
<hi***************@gmx.at> wrote:
"CMM" <cm*@nospam.com> schrieb:
1) The property is ReadOnly... like is often the case when you expose
collections or another complex object. You usually do this when you want
to maintain a particular instance of an object for whatever reason, allow
external classes to manipulate but not "switch" the object, but, inside
the class you should be able to do whatever you want with the object.


VB 2005 supports different levels of visibility for 'Get' and 'Set'.


Like this?
---
Private m_MyValue As Integer
Public Property MyValue() As Integer
Get
Return m_MyValue
End Get
Private Set(ByVal value As Integer)
m_MyValue = value
End Set
End Property
---

Thank you. Just looked it up in the documentation.

I don't think I would ever have known about this
possibility unless someone pointed it out to me.

Don't think I have seen its usage in any source
samples I have come across, but this looks useful.

/JB

Feb 22 '06 #17
On Wed, 22 Feb 2006 12:55:06 -0500, "CMM" <cm*@nospam.com> wrote:
I meant Me is used with Properties (Me.PropertyX = someValue). For member
variables you don't need to because usually their camelCase and/or
scope_notation ("m_" or "_" which is also not required... though camelCase
is) is enough.


Unless the field is prefixed with "m_" or "_", I would not necessarily
interpret a camelCased variable used in a method as a member variable.

It could just as well be a parameter, since the Microsoft guidelines
for parameters specify camelCasing.

So if "Me." was used to identify member variables or their accessors,
why not go all the way and use it to indicate that any method or
function call prefixed with "Me." belonged to the class? Where should
the line be drawn?

Methinks Me is overused. It's late here in GMT+1. Me is tired now :)

/JB

Feb 22 '06 #18
I guess the assumption is that the class should know not to give a private
member an "invalid" value that would otherwise not be possible using the
Accessor.... and if it does do so, it's doing it *knowingly.*
In the interest of maintainability, if performance is not an issue,
standardizing on going through the accessor all the time might
not be a bad idea: Could catch a few programming errors when
the class is modified later. Suppose we have an uninitialized
ArrayList member variable and the accessor knows that it should
be created on first access. Using the member variable directly,
one would have to make this check all the places it is being used,
unless - for some reason - it is known that it has already been
created at whatever point it is being used - something that would
require a greater knowledge of the class than just the function
being written/modified.
Furthermore, it depends on what the class *does* IMHO, a "Property Accesor
Only" class might work well for regular ol' entity classes that represent
"data" (like a Person class) but not so much for a Custom Control, Form, or
other "action" oriented class that does more than just house information.


Yes, I am beginning to firmly believe that the answer to the whole
debate is: "It depends".

I have learned a couple of things today.

Regards,

JB

Feb 22 '06 #19
CMM
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:al********************************@4ax.com...
On Wed, 22 Feb 2006 12:55:06 -0500, "CMM" <cm*@nospam.com> wrote:
I meant Me is used with Properties (Me.PropertyX = someValue). For member
variables you don't need to because usually their camelCase and/or
scope_notation ("m_" or "_" which is also not required... though camelCase
is) is enough.
Unless the field is prefixed with "m_" or "_", I would not necessarily
interpret a camelCased variable used in a method as a member variable.


Common convention says it doesn't matter. Just like it doesn't matter if a
variable is a parameter or a local. Likewise, you also don't need to scope
global variables with "g_" or constants with upper_case.

Note: I don't necessarily agree with this on a personal level..... just
stating what is a common tide nowadays. I don't disagree with it either....
if you use it for a while you might find it's quite liberating and doesn't
take away from code readability at all.

It could just as well be a parameter, since the Microsoft guidelines
for parameters specify camelCasing.
MS guideliness call for camelCasing for all variables. PascalCasing for
public members.

So if "Me." was used to identify member variables or their accessors,
why not go all the way and use it to indicate that any method or
function call prefixed with "Me." belonged to the class? Where should
the line be drawn?
The line is drawn at Properties. Simple as that. Why? Well, because you
don't use Me to indicate scope (again, it doesn't matter) you're using it to
indicate that you're accessing a temporal attribute of the class.

Methinks Me is overused. It's late here in GMT+1. Me is tired now :)


Me.HearsYa = True

;-)

Feb 22 '06 #20
CMM
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:4a********************************@4ax.com...
<snip>Could catch a few programming errors when
the class is modified later. Suppose we have an uninitialized
ArrayList member variable and the accessor knows that it should
be created on first access. <snip>


I'm a strong advocate for initializing in the declaration (and so is MS in
their guidelines and the entire world outside of VB).

'arrays should be initialized
Private myArray As Integer() = {}

'objects should be initialized (most of the time)
Private myArrayList As New ArrayList

'and, yes, string objects should be initialized and not left as Nothing
'unless you actually need to do something particular with "Nothing."
Private myStr As String = String.Empty

This initialize-in-declaration is less less important IF you do NOT provide
a default New() and instead *require* parameters to be passed into it ( like
New(ary, arrayList, str) )
Feb 22 '06 #21
"CMM" <cm*@nospam.com> schrieb:
<snip>Could catch a few programming errors when
the class is modified later. Suppose we have an uninitialized
ArrayList member variable and the accessor knows that it should
be created on first access. <snip>


I'm a strong advocate for initializing in the declaration (and so is MS in
their guidelines and the entire world outside of VB).

'arrays should be initialized
Private myArray As Integer() = {}

'objects should be initialized (most of the time)
Private myArrayList As New ArrayList

'and, yes, string objects should be initialized and not left as Nothing
'unless you actually need to do something particular with "Nothing."
Private myStr As String = String.Empty


I think this depends on the particular case. Especially for strings an
empty string means something differently from a 'Nothing' reference. A
'Person' class with a 'FirstName' property of type 'String' could indicate
an unknown first name if the property is set to 'Nothing' and an empty (no)
first name if the property is set to an empty string.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #22
CMM
"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:ei**************@TK2MSFTNGP12.phx.gbl...
"CMM" <cm*@nospam.com> schrieb:
I'm a strong advocate for initializing in the declaration (and so is MS
in their guidelines and the entire world outside of VB).

'arrays should be initialized
Private myArray As Integer() = {}

'objects should be initialized (most of the time)
Private myArrayList As New ArrayList

'and, yes, string objects should be initialized and not left as Nothing
'unless you actually need to do something particular with "Nothing."
Private myStr As String = String.Empty


I think this depends on the particular case. Especially for strings an
empty string means something differently from a 'Nothing' reference. A
'Person' class with a 'FirstName' property of type 'String' could indicate
an unknown first name if the property is set to 'Nothing' and an empty
(no) first name if the property is set to an empty string.


Which is why I said "unless you actually need to do something particular
with 'Nothing.'" Nonetheless, I'd prefer to use DBNull in the scenerio you
outline. I have never (well, maybe once with XML files ;-) )had to use
Nothing.String for anything. Nothing does NOT mean "missing data"(!... well
it could if you as the programmer wanted it to).... it means "uninitialized
value."

From MSDN:
"The System.DBNull value indicates that the Object represents missing or
nonexistent data. DBNull is not the same as Nothing, which indicates that a
variable has not yet been initialized. DBNull is also not the same as a
zero-length string (""), which is sometimes referred to as a null string."

--
-C. Moya
www.cmoya.com

Feb 22 '06 #23
"CMM" <cm*@nospam.com> schrieb:
I'm a strong advocate for initializing in the declaration (and so is MS
in their guidelines and the entire world outside of VB).

'arrays should be initialized
Private myArray As Integer() = {}

'objects should be initialized (most of the time)
Private myArrayList As New ArrayList

'and, yes, string objects should be initialized and not left as Nothing
'unless you actually need to do something particular with "Nothing."
Private myStr As String = String.Empty
I think this depends on the particular case. Especially for strings an
empty string means something differently from a 'Nothing' reference. A
'Person' class with a 'FirstName' property of type 'String' could
indicate an unknown first name if the property is set to 'Nothing' and an
empty (no) first name if the property is set to an empty string.


Which is why I said "unless you actually need to do something particular
with 'Nothing.'" Nonetheless, I'd prefer to use DBNull in the scenerio you
outline. I have never (well, maybe once with XML files ;-) )had to use
Nothing.String for anything. Nothing does NOT mean "missing data"(!...
well it could if you as the programmer wanted it to).... it means
"uninitialized value."


IMO it simply means "variable not pointing to an instance" without further
semantics. However, it's possible to assign further semantics to variables
pointing to 'Nothing'.
From MSDN:
"The System.DBNull value indicates that the Object represents missing or
nonexistent data. DBNull is not the same as Nothing, which indicates that
a variable has not yet been initialized. DBNull is also not the same as a
zero-length string (""), which is sometimes referred to as a null string."


I think the sentence "indicates that a variable not yet been initialized" is
unfortunate. Variables can even be initialized with 'Nothing' or can be set
to 'Nothing' later on while the program is executing. The documentation for
'Nothing' contains a more appropriate description: "If the variable is of a
reference type ó that is, an object variable ó 'Nothing' means the variable
is not associated with any object".

Using DBNull is not always an option, for example, it cannot be directly
assigned to a property of type 'String'. It's a pretty obvious observation
that 'DBNull.Value' is not the same as a 'Nothing' reference or an empty
string. BTW: I have rarely seen the term "null string" for a zero-length
(empty) string.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 22 '06 #24
CMM
> string. BTW: I have rarely seen the term "null string" for a zero-length
(empty) string.


Yeah. Me either.
NullString is yet ANOTHER thing... at least classically in VB.Classic...
where vbNullString is used to pass C null-terminated empty strings to API's.

I don't disagree with your NothingString comments either. But, I don't think
I have ever encountered a situation where a dependency set my strings back
to Nothing. IMO, NothingStrings' usefulness is extremely rare and
specialized. Using them or not taking care to avoid them leads to needless
fragility in complex applications. I'm NOT saying that they're useless....
just that their usefulness is rare.

--
-C. Moya
www.cmoya.com
Feb 23 '06 #25
On Wed, 22 Feb 2006 15:12:37 -0500, "CMM" <cm*@nospam.com> wrote:
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:4a********************************@4ax.com.. .
<snip>Could catch a few programming errors when
the class is modified later. Suppose we have an uninitialized
ArrayList member variable and the accessor knows that it should
be created on first access. <snip>
I'm a strong advocate for initializing in the declaration (and so is MS in
their guidelines and the entire world outside of VB).


I must go read that. Suppose the initializations are independent,
such as

Dim _myA As Integer = 2
Dim _myB As Integer = _myA * 2
Dim _myC As Integer = _myA + _myB

you cannot just change the order of declarations, but if that sequence
of initializations was made in a code block, you could swap them
around all you liked, as long as the sequence in the code block
remained the same.
'arrays should be initialized
Private myArray As Integer() = {}

'objects should be initialized (most of the time)
Private myArrayList As New ArrayList


Suppose we are dealing with a more complex (and expensive) object
which might not be needed during the lifetime of the instance of the
class. Would you want to initialize such an object at declaration time
or on first use? In VB6, "Dim X As New SomeObject" meant that the
instance X was only created if it was referenced - something that went
against the general recommendations for performance reasons
(every reference to X was wrapped in code checking for the existence
of X behind the scenes, which would bloat the compiled .exe), but for
*expensive* objects, I still think a similar pattern has its uses.

I think FxCop by default warns about unnecessary initialization, i.e.
Integer = 0, Boolean = False, etc. Something I'm not sure I agree
with, since I like all my initializations to be explicit - whether at
declaration time or in an initialization code block.

/JB

Feb 23 '06 #26
CMM
> Suppose we are dealing with a more complex (and expensive) object
which might not be needed during the lifetime of the instance of the
class. Would you want to initialize such an object at declaration time
or on first use? In VB6, "Dim X As New SomeObject" meant that the <snip>

The question to ask in that case is "why is this variable at the method
level?" Method level variables are usually the lazy programmers way of
passing around data (bad code!) instead of as parameters. Having said that,
I can see what you're saying. Like with everything else, no rule is
absolute. There are clearly cases (in Property Accessor/ Value variables)
where not initializing them is *intentionally* part of the design.

Keep in mind though that object creation (unless it does some creepy IO in
its constructor) is in no way expensive in VB.NET. A class with 1000 lines
of code takes the same amount of time to instantiate as a class with 2 lines
of code. (I'm talking method/code here, not data). VB.Classic had problems
because of ref counting and stuff like that.... but even back then the
"expense" of creating objects (as opposed to say structures) was way
overhyped IMO. In. .NET, the expense (even for big complex classes) is
virtually 0.

Inside methods, the pattern is even clearer. Objects should be Dim'd exactly
when they are needed rather than at the top of the method as was the
VB.Classic practice. If their reference is based on a conditional then it's
ok to create them unitialized and then set right afterwards. But if their
value is known and not condition based they should always be initialized.

Correct Usage Patterns (arguably)

Dim o As New SomeClass
---
Dim o As SomeClass = SomeObjA
---
Dim o As SomeClass
If someConditional Then
o = SomeObjA
Else
o = SomeObjB
End If
---
For Each o As SomeClass In SomeCollection
...
Next o
---
If someConditional Then
Dim o As New SomeClass
...
End If 'object instantly goes of scope

--
-C. Moya
www.cmoya.com
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:in********************************@4ax.com... On Wed, 22 Feb 2006 15:12:37 -0500, "CMM" <cm*@nospam.com> wrote:
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:4a********************************@4ax.com. ..
<snip>Could catch a few programming errors when
the class is modified later. Suppose we have an uninitialized
ArrayList member variable and the accessor knows that it should
be created on first access. <snip>


I'm a strong advocate for initializing in the declaration (and so is MS in
their guidelines and the entire world outside of VB).


I must go read that. Suppose the initializations are independent,
such as

Dim _myA As Integer = 2
Dim _myB As Integer = _myA * 2
Dim _myC As Integer = _myA + _myB

you cannot just change the order of declarations, but if that sequence
of initializations was made in a code block, you could swap them
around all you liked, as long as the sequence in the code block
remained the same.
'arrays should be initialized
Private myArray As Integer() = {}

'objects should be initialized (most of the time)
Private myArrayList As New ArrayList


Suppose we are dealing with a more complex (and expensive) object
which might not be needed during the lifetime of the instance of the
class. Would you want to initialize such an object at declaration time
or on first use? In VB6, "Dim X As New SomeObject" meant that the
instance X was only created if it was referenced - something that went
against the general recommendations for performance reasons
(every reference to X was wrapped in code checking for the existence
of X behind the scenes, which would bloat the compiled .exe), but for
*expensive* objects, I still think a similar pattern has its uses.

I think FxCop by default warns about unnecessary initialization, i.e.
Integer = 0, Boolean = False, etc. Something I'm not sure I agree
with, since I like all my initializations to be explicit - whether at
declaration time or in an initialization code block.

/JB

Feb 23 '06 #27
On Wed, 22 Feb 2006 22:33:40 -0500, "CMM" <cm*@nospam.com> wrote:
Suppose we are dealing with a more complex (and expensive) object
which might not be needed during the lifetime of the instance of the
class. Would you want to initialize such an object at declaration time
or on first use? In VB6, "Dim X As New SomeObject" meant that the

<snip>

The question to ask in that case is "why is this variable at the method
level?" Method level variables are usually the lazy programmers way of
passing around data (bad code!) instead of as parameters. Having said that,
I can see what you're saying. Like with everything else, no rule is
absolute. There are clearly cases (in Property Accessor/ Value variables)
where not initializing them is *intentionally* part of the design.


I was thinking about a usercontrol wrapping a tabcontrol with a number
of tabpages, each of which contains a usercontrol wrapping the
controls for that page. In some cases, initializing all pages at once
is desired (i.e. long wait the first time the tabcontrol is
displayed).
In other cases, we want to display the tabcontrol as quickly as
possible, but only initialize the individual tabpages as they are
being selected by the user.

Then, of course, there are the high-volume cases where tens of
thousands instances of a class need to be instantiated in a short
span of time and where every little unnecessary instantiation takes
time (e.g. if the instantiated object creates a new GUID or similar).

I agree with the rest of your statements about usage patterns inside
methods. I am only talking about the class' members.

/JB
Feb 23 '06 #28
CMM


--
-C. Moya
www.cmoya.com
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:bs********************************@4ax.com...
On Wed, 22 Feb 2006 22:33:40 -0500, "CMM" <cm*@nospam.com> wrote:
Suppose we are dealing with a more complex (and expensive) object
which might not be needed during the lifetime of the instance of the
class. Would you want to initialize such an object at declaration time
or on first use? In VB6, "Dim X As New SomeObject" meant that the

<snip>

The question to ask in that case is "why is this variable at the method
level?" Method level variables are usually the lazy programmers way of
passing around data (bad code!) instead of as parameters. Having said
that,
I can see what you're saying. Like with everything else, no rule is
absolute. There are clearly cases (in Property Accessor/ Value variables)
where not initializing them is *intentionally* part of the design.


I was thinking about a usercontrol wrapping a tabcontrol with a number
of tabpages, each of which contains a usercontrol wrapping the
controls for that page. In some cases, initializing all pages at once
is desired (i.e. long wait the first time the tabcontrol is
displayed).
In other cases, we want to display the tabcontrol as quickly as
possible, but only initialize the individual tabpages as they are
being selected by the user.

Then, of course, there are the high-volume cases where tens of
thousands instances of a class need to be instantiated in a short
span of time and where every little unnecessary instantiation takes
time (e.g. if the instantiated object creates a new GUID or similar).

I agree with the rest of your statements about usage patterns inside
methods. I am only talking about the class' members.

/JB

Feb 23 '06 #29
CMM
Sorry... hit send too soon.

Anyway. I see what you mean. In the first example "the initialize as soon as
possible" idea doesn't extend to elements of a collection (your tab page
contents). Though it does apply to the collection instance itself (it can
instantiated, but empty and filled as needed). Forms and Controls are tricky
because Painting/Redraw is a big bottleneck as is the Win32 Messaging
Subsystem. That's why they have those SuspendLayout and BeginUpdate
mechanisms....

In the second example, there's no doubt some rare classes might necessitate
a first-use sort of mechanism on some of their Property Accessors and
underlying values... though I venture to say this is rarer than you think
and needs study before you actually spend time doing it. For instance....
using GUID your example.... on my machine and in debug mode it takes 15ms to
create 10,000 guid's and add them to an ArrayList! That's less than a blink
of an eye.

--
-C. Moya
www.cmoya.com
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> wrote in message
news:bs********************************@4ax.com...
On Wed, 22 Feb 2006 22:33:40 -0500, "CMM" <cm*@nospam.com> wrote:
Suppose we are dealing with a more complex (and expensive) object
which might not be needed during the lifetime of the instance of the
class. Would you want to initialize such an object at declaration time
or on first use? In VB6, "Dim X As New SomeObject" meant that the

<snip>

The question to ask in that case is "why is this variable at the method
level?" Method level variables are usually the lazy programmers way of
passing around data (bad code!) instead of as parameters. Having said
that,
I can see what you're saying. Like with everything else, no rule is
absolute. There are clearly cases (in Property Accessor/ Value variables)
where not initializing them is *intentionally* part of the design.


I was thinking about a usercontrol wrapping a tabcontrol with a number
of tabpages, each of which contains a usercontrol wrapping the
controls for that page. In some cases, initializing all pages at once
is desired (i.e. long wait the first time the tabcontrol is
displayed).
In other cases, we want to display the tabcontrol as quickly as
possible, but only initialize the individual tabpages as they are
being selected by the user.

Then, of course, there are the high-volume cases where tens of
thousands instances of a class need to be instantiated in a short
span of time and where every little unnecessary instantiation takes
time (e.g. if the instantiated object creates a new GUID or similar).

I agree with the rest of your statements about usage patterns inside
methods. I am only talking about the class' members.

/JB

Feb 23 '06 #30
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb:
In VB6, "Dim X As New SomeObject" meant that the
instance X was only created if it was referenced - something that went
against the general recommendations for performance reasons
(every reference to X was wrapped in code checking for the existence
of X behind the scenes, which would bloat the compiled .exe), but for
*expensive* objects, I still think a similar pattern has its uses.


Well, that's what 'WeakReference' is basically for, except that its behavior
is different in matters of object destruction.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Feb 23 '06 #31
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb:
VB 2005 supports different levels of visibility for 'Get' and 'Set'.


Like this?
---
Private m_MyValue As Integer
Public Property MyValue() As Integer
Get
Return m_MyValue
End Get
Private Set(ByVal value As Integer)
m_MyValue = value
End Set
End Property
---

Don't think I have seen its usage in any source
samples I have come across, but this looks useful.


Well, this is possible since VB 2005 and not supported by VB.NET 2002/2003.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>
Feb 23 '06 #32
Herfried,

I had to look 3 times before I saw it, you know probably what the
intelisence gives back on such a property?

Cor
Feb 23 '06 #33
Carlos,

Although the sample from Joergen is inviting to pass the checking in the
property rules by using the method (therefore my answer) do I use myself
forever the private members inside the class.

The main reason is that I hate it when I am debugging step by step to see
the code go up and down.

Cor
Feb 23 '06 #34
"Cor Ligthert [MVP]" <no************@planet.nl> schrieb:
I had to look 3 times before I saw it, you know probably what the
intelisence gives back on such a property?


Sorry, I cannot follow you...

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>
Feb 23 '06 #35
On Thu, 23 Feb 2006 10:54:19 +0100, "Herfried K. Wagner [MVP]"
<hi***************@gmx.at> wrote:
"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNOSPAM> schrieb:
In VB6, "Dim X As New SomeObject" meant that the
instance X was only created if it was referenced - something that went
against the general recommendations for performance reasons
(every reference to X was wrapped in code checking for the existence
of X behind the scenes, which would bloat the compiled .exe), but for
*expensive* objects, I still think a similar pattern has its uses.


Well, that's what 'WeakReference' is basically for, except that its behavior
is different in matters of object destruction.


WeakReference - as I understand it - is used for tracking the state of
a previously created object which may or may not have been garbage
collected, i.e. it can be used to figure out if an object is still
alive and can be reused or if it needs to be recreated.

I do not see where WeakReference applies to any objects that have
not been created in the first place(?)

/JB

Feb 23 '06 #36
CMM
Yeah me too!!!

Though I guess if you 1) Use Me. on Accessors and 2) camelCase on vars it's
A LOT easier to tell at a glance when you're about to step *into* an
Accessor and hit F10 to step over it. :-)

--
-C. Moya
www.cmoya.com
"Cor Ligthert [MVP]" <no************@planet.nl> wrote in message
news:ej**************@TK2MSFTNGP10.phx.gbl...
Carlos,

Although the sample from Joergen is inviting to pass the checking in the
property rules by using the method (therefore my answer) do I use myself
forever the private members inside the class.

The main reason is that I hate it when I am debugging step by step to see
the code go up and down.

Cor

Feb 23 '06 #37
On Thu, 23 Feb 2006 11:35:52 +0100, "Cor Ligthert [MVP]"
<no************@planet.nl> wrote:
Carlos,

Although the sample from Joergen is inviting to pass the checking in the
property rules by using the method (therefore my answer) do I use myself
forever the private members inside the class.

The main reason is that I hate it when I am debugging step by step to see
the code go up and down.

Cor


You can decorate your property Get/Sets with the
DebuggerStepThrough attribute to get around that, so
that in itself is not an argument for going the direct route.

Problem is, with properties, the attribute has to be
applied to the Get function and Set method individually,
rather than the whole property itself, which messes up
the indentation and makes the code less readable, i.e.:

Public Property DragForm() As Boolean
<System.Diagnostics.DebuggerStepThrough()> _
Get
Return _DragForm
End Get
<System.Diagnostics.DebuggerStepThrough()> _
Set(ByVal value As Boolean)
If _DragForm = value Then
Return
End If
_DragForm = value
End Set
End Property

Other than disabling the auto-formatting of the source, I don't
see how this problem can be solved. :(

/JB

Feb 23 '06 #38

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Peter Frost | last post: by
5 posts views Thread by Harold Hsu | last post: by
reply views Thread by jack112 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.