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

J

Joergen Bech

(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
 
C

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

Cor Ligthert [MVP]

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
 
H

Herfried K. Wagner [MVP]

Joergen Bech @ post1.tele.dk> said:
---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.
 
H

Herfried K. Wagner [MVP]

Cor Ligthert said:
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.
 
J

Joergen Bech

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
 
J

Joergen Bech

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
 
C

Cor Ligthert [MVP]

Maybe can the only problem be that you come in trouble in version 2005
Well, but this does not apply to private variables.

--

So I wrote it correct?

:)

Cor
 
C

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).
 
J

Joergen Bech

.... 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
 
H

Herfried K. Wagner [MVP]

Joergen Bech @ post1.tele.dk> said:
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.
 
H

Herfried K. Wagner [MVP]

CMM said:
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?
 
C

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

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.
 
H

Herfried K. Wagner [MVP]

CMM said:
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'.
 
J

Joergen Bech

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
 
J

Joergen Bech

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
 
J

Joergen Bech

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
 
C

CMM

Joergen Bech @ post1.tele.dk> said:
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

;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top