Static Class Constants (VB 2005)

  • Thread starter Thread starter Michael D. Ober
  • Start date Start date
M

Michael D. Ober

Is there any way to create a constant in a class that can be used both with
an instantiated object and without. For example:

dim ClassConst as string = myClass.ConstantString

dim myObj = new MyClass
ClassConst = myObj.ConstantString

Inside the class MyClass

Class MyClass

public const ConstantString = "Some Constant String"

End Class

In Beta 2, ConstantString was available in either of the above cases without
complaint. In the RTM version, I can't do both. I don't want to turn off
the warning as doing so may actually introduce another bug in my code later
because I didn't see the warning.

Thanks,
Mike.
 
If it's a constant, why not always reference it through the type name? What
do you gain by accessing it through an instance?
 
Marina,

Marina said:
If it's a constant, why not always reference it through the type name?
What do you gain by accessing it through an instance?

What do you loose by accessing it through an instance?
 
Michael


i use the release version of Visual studio 2005 ( professional edition )

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim ClassConst As String = XMyClass.ConstantString

MsgBox(ClassConst)

Dim myObj = New XMyClass

ClassConst = myObj.ConstantString

MsgBox(ClassConst)

End Sub

End Class

Class XMyClass

Public Const ConstantString = "Some Constant String"

End Class

this works without anny problems on my dev computer ( no warnings )

regards

Michel Posseth [MCP]
 
Code readability.

Mike.

Marina said:
If it's a constant, why not always reference it through the type name? What
do you gain by accessing it through an instance?
 
Apparently you lose the ability to compile without getting a warner. You
also lose code clarity, as now it is not obvious this is a constant. It
could just be an instance property of the class, and it's not at all obvious
that it is not. Where as seeing the type name in front, you see that this
something that exists only once for the class.

The point is, if you don't gain anything by doing it, and you lose
readability, then why do it?
 
There are times when accessing through an instance makes more sense - it
ensures I'm working with the correct object/class type. Other times,
accessing through the class type make more sense - when trying to verify
class type of an unknown string representation of the object. In the latter
case, class type verification can then be done without the overhead of
creating an object that then gets immediately thrown away.

Mike Ober.
 
Regardless of Option Explicit and Option Strict settings on a brand new form
with a single button, I get the error "Access of shared member, constant
member, enum member or nested type through an instance; qualifying
expression will not be evaluated." on your code sample. VS 2005 Standard
RTM.

Mike.

m.posseth said:
Michael


i use the release version of Visual studio 2005 ( professional edition )

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim ClassConst As String = XMyClass.ConstantString

MsgBox(ClassConst)

Dim myObj = New XMyClass

''''''''''''' Error is on this line
ClassConst = myObj.ConstantString

MsgBox(ClassConst)

End Sub

End Class

Class XMyClass

Public Const ConstantString = "Some Constant String"

End Class

this works without anny problems on my dev computer ( no warnings )

regards

Michel Posseth [MCP]


Michael D. Ober said:
Is there any way to create a constant in a class that can be used both
with
an instantiated object and without. For example:

dim ClassConst as string = myClass.ConstantString

dim myObj = new MyClass
ClassConst = myObj.ConstantString

Inside the class MyClass

Class MyClass

public const ConstantString = "Some Constant String"

End Class

In Beta 2, ConstantString was available in either of the above cases
without
complaint. In the RTM version, I can't do both. I don't want to turn off
the warning as doing so may actually introduce another bug in my code
later
because I didn't see the warning.

Thanks,
Mike.
 
If this is about a constant, how does that help ensure you are working with
the right class? There is no inheritance issue here.
 
Marina said:
If this is about a constant, how does that help ensure you are working
with the right class? There is no inheritance issue here.

That's true, but especially when dealing with public constants it seems
completely irrelevant to me whether or not the member belongs to an instance
or the class itself. I agree that it doesn't make much sense to obtain a
reference to an object using complicated code only to access one of the
public constants of the class.
 
I think for readability issues, and to make the developer aware that they
are accessing a constant or static member, that warning is there.

And that is why it is a warning, not an error. So if it's something one
wants to do, they can. Though again, for readability and consistentcy
reasons my opinion is that the class name should be used in these cases.
 
Yes, this is a change in the VB.NET language and you will be force to change
it. C#, and other languages have always done it this way.

I think for the sake of better code clarity it was a good move, also this
does not require any more work from the developer.
It's is now obvious if a line of code is calling a shared/static or instance
specific method.
It can be a pain when moving code from 1.0 to 2.0, but at least the error is
easy to identify, and easy to fix.

Schneider.




Michael D. Ober said:
Regardless of Option Explicit and Option Strict settings on a brand new form
with a single button, I get the error "Access of shared member, constant
member, enum member or nested type through an instance; qualifying
expression will not be evaluated." on your code sample. VS 2005 Standard
RTM.

Mike.

m.posseth said:
Michael


i use the release version of Visual studio 2005 ( professional edition )

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim ClassConst As String = XMyClass.ConstantString

MsgBox(ClassConst)

Dim myObj = New XMyClass

''''''''''''' Error is on this line
ClassConst = myObj.ConstantString

MsgBox(ClassConst)

End Sub

End Class

Class XMyClass

Public Const ConstantString = "Some Constant String"

End Class

this works without anny problems on my dev computer ( no warnings )

regards

Michel Posseth [MCP]


Michael D. Ober said:
Is there any way to create a constant in a class that can be used both
with
an instantiated object and without. For example:

dim ClassConst as string = myClass.ConstantString

dim myObj = new MyClass
ClassConst = myObj.ConstantString

Inside the class MyClass

Class MyClass

public const ConstantString = "Some Constant String"

End Class

In Beta 2, ConstantString was available in either of the above cases
without
complaint. In the RTM version, I can't do both. I don't want to turn off
the warning as doing so may actually introduce another bug in my code
later
because I didn't see the warning.

Thanks,
Mike.
 
schneider said:
Yes, this is a change in the VB.NET language and you will be force to
change
it.

No! It's a warning which can be disabled.
C#, and other languages have always done it this way.

VB is not C#. The keyword is called 'Shared' in VB.NET. Shared members are
/shared/ between /all/ instances of a class. They belong to all instances
and thus are accessible on instance variables.
 
Mike,

\\\
Public Class myConstantClass
Private Shared mValue As String = "WhatEverConstantString"
Public Shared ReadOnly Property ConstantString() As String
Get
Return mValue
End Get
End Property
End Class
///

I hope this helps,

Cor
 
Cor Ligthert said:
\\\
Public Class myConstantClass
Private Shared mValue As String = "WhatEverConstantString"
Public Shared ReadOnly Property ConstantString() As String
Get
Return mValue
End Get
End Property
End Class
///

I doubt that this will solve the OP's problem, which is the same in both
cases, regardless if you are using a constant or a read-only property: A
shared member is accessed through a variable of the class' type.
 
i have the idea that this is not what the TS wants


and Cor why not
Public Class myConstantClass

Public Shared ReadOnly Property ConstantString() As String

Get

Return "WhatEverConstantString"

End Get

End Property

End Class

And indeed it turned out that my IDE had two warning options off

so with this code

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim ClassConst As String = XMyClass.ConstantString

MsgBox(ClassConst)

Dim myObj As New XMyClass

ClassConst = myObj.ConstantString

MsgBox(ClassConst)

End Sub

End Class

Class XMyClass

Public Const ConstantString As String = "Some Constant String"

End Class



i see a nag under this line myObj.ConstantString

i think the best solution would be to declare all these sort constants as
readonly property`s with the shared keyword

regards

Michel posseth
 
Herfried K. Wagner [MVP] wrote:

Sorry Herfried, I have to take issue with you on this one I'm afraid
No! It's a warning which can be disabled.

It's a warning that you're doing something wrong.
VB is not C#.
The keyword is called 'Shared' in VB.NET.

There's a keyword called 'AddressOf' as well, but it doesn't get the
address of anything.
Shared members are
/shared/ between /all/ instances of a class.
They belong to all instances

No, conceptually they belong to the *class*, not to any instance.
and thus are accessible on instance variables.

Them being accessible on instance variables was to my mind a language
design error.

Note that Shared items can be accessed even when a class *cannot* have
instances - how can they then be said to 'belong to all instances' ?

This new compiler warning is a good thing.
 
Larry Lard said:
Sorry Herfried, I have to take issue with you on this one I'm afraid

No problem. I like those "issues" ;-).
It's a warning that you're doing something wrong.

Well, it's an error if you configure the compiler to raise a complile-time
error. And it's not problem if you configure the compiler to take no action
at all. Although I have never accessed a shared member through an instance
variable, I don't think that this is such a big problem. Maybe it's a
problem for C# developers who come to VB.
There's a keyword called 'AddressOf' as well, but it doesn't get the
address of anything.

Well, that's another story. I remember Bruce McKinney first complaining
about the existance of 'AddressOf' in VB.NET some years ago. I believe that
a keyword is important, regardless of its name. Personally, I do not like
the C# solution.
No, conceptually they belong to the *class*, not to any instance.

As already said, this doesn't apply to VB.NET. It's an implementation
detail that they do not belong to a certain instance.

"Visual Basic Language Specification -- 9.2.4 'Shared' Methods":

| The 'Shared' modifier indicates a method is a /shared method/.
| A shared method does not operate on a specific instance of a type
| and may be invoked directly from a type rather than through a particular
| instance of a type. It is valid, however, to use an instance to qualify
| a shared method.

"Visual Basic Language Concepts -- Shared Members":

| Shared members are properties, procedures, and fields that are shared
| by all instances of a class.

"Visual Basic Language Reference -- 'Shared'":

| The 'Shared' keyword indicates that one or more declared programming
| elements are shared. Shared elements are not associated with a specific
| instance of a class or structure. You can access them by qualifying them
| either with the class or structure name, or with the variable name of a
| specific instance of the class or structure.

....
Them being accessible on instance variables was to my mind a language
design error.

Note that Shared items can be accessed even when a class *cannot* have
instances - how can they then be said to 'belong to all instances' ?

They belong to the set of instances, which can be empty.
This new compiler warning is a good thing.

Well, I'm glad that it can be disabled...
 
Michael and Herfried,

Just because my idea was, what is the benefit of a constant in 2005.

In my opinion is this much nicer to get the same result.

I was sure somebody would give a reaction on my sample.

Cor
 
"Herfried K. Wagner [MVP]"

Probably we don't disagree if you have read what I write 3 or 4 times.
VB is not C#. The keyword is called 'Shared' in VB.NET. Shared members
are /shared/ between /all/ instances of a class. They belong to all
instances and thus are accessible on instance variables.
And the normal way is to place those in the first (0) stack of the program.
I don't know how Net does it, however I assume the same or otherwise the
method will result in the same.

In my opinion it is what is called a shared class no class but a module.

That in the C world people started to call this a class because of the fact
that it was in almost the same way described does not mean that it is a
class. (Despite that in my opinion all dificult ways in describing are
choosen to avoid to tell this)

I see not why it can than not used as a real class and automaticly take no
care of the "Shared" keyword..

That in the German language "See" is in English "Lake" what in Dutch "Meer"
while in French "Mer" is the same as in English "See" does not say anything
about the used object at all.

Just my thought,

Cor
 

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

Back
Top