Constants can't be defined in a namespace. WTH?

P

PC

Gentlesofts,

Forgive me. I'm an abject newbie in your world, using VB 2005 with the
dot-Net wonderfulness.


So, I'm writing a wonderful class or two to interface with a solemnly
ancient database. In times recently past, I would have done this with
Borland Delphi. So, that's my perspective and I have my old Delphi
code to crib from. That seems good.


So, to make sense of the ancient database, we need a wonderful set of
CONSTANTs. Programs using the VB classes will need to have some
knowledge of the CONSTANTs -- i.e. they need to be publically visible.
That seems (arguably) good.


So, I have understood that NAMESPACEs are a wonderful new thing and I
see their value and I'm writing my ancient database classes and
utilities in a new NAMESPACE named, sentimentally, after the long lost
DBMS. That seems good.


So, I define the CONSTANTs with code like this...

Const DES_REC_OUTPUT_PAT As Integer = 14

These CONSTANTs are within the NAMESPACE, but outside of any CLASS
definition. That seems like it should be good, but VS brands the code
with a pestilent wavy line and announces...

"Statement is not valid in a namespace"


So, I ask you gently, "WTH?"

The wonderful HELP Oracle tells me that I can define many things within
a NAMESPACE, including classes, structures and (notably) ENUMERATIONs.
But NOT CONSTANTs.


So again, I'm new to your culture. But, I don't understand why a
NAMESPACE can include ENUMERATIONs but NOT CONSTANTs. These things are
semantic sisters and I just don't get the distinction. To my way of
thinking, this appears to be a flat-out defect in the language. Feel
free to set me straight.


So most importantly, could someone offer a wonderful way to implement
the functionality -- something more consistent with the philosophies of
this VB dot-Net culture? My current thinking is that I might implement
a static class to contain the constants. Does that seem good?


TIA and Love, PC
 
T

Tim Patrick

I can't speak for the reasons why Microsoft decided against allowing constants
in the namespace level. Perhaps it is that only definitions of objects can
exist in the namespace, but that actual instances of objects (such as constants
and variables) must exist within a class. That seems valid to me, but again,
I'm just one programmer.

Normally, when you have a constant that you want to use appliation-wide,
you create a Visual Basic "Module." It acts a lot like a static class, although
you can't create instances of it. You just refer to any Public member of
that Module from anywhere in your application.

Module GeneralCode
Const DES_REC_OUTPUT_PAT As Integer = 14
End Module

' ...elsewhere...

Class MyClass
Public Sub MySub()
Dim myLocalVariable As Integer = DES_REC_OUTPUT_PAT
End Sub
End Class
 
P

PC

Tim Patrick wrote:

I can't speak for the reasons why Microsoft decided against allowing
constants in the namespace level. Perhaps it is that only definitions
of objects can exist in the namespace, but that actual instances of
objects (such as constants and variables) must exist within a class.
That seems valid to me, but again, I'm just one programmer.

It didn't occur to me, but VB constants are indeed objects. Things like
MY_SPECIAL_CONSTANT.AsString are happily accepted. Being an elderly
one, I want to use constants in the same way that one might have used
DEFINEd macro constants in C, i.e. as simple value substitutes. The
presumed overhead of the objectivity seems like a shame, but there it
is.

Of course, one could argue that "Const" statements are also
declarations. Not allowing constants in a namespace still strikes me
as an oversight.

Normally, when you have a constant that you want to use
appliation-wide, you create a Visual Basic "Module." It acts a lot
like a static class, although you can't create instances of it. You
just refer to any Public member of that Module from anywhere in your
application.

Module GeneralCode
Const DES_REC_OUTPUT_PAT As Integer = 14
End Module

' ...elsewhere...

Class MyClass
Public Sub MySub()
Dim myLocalVariable As Integer = DES_REC_OUTPUT_PAT
End Sub
End Class

I was going to define a class called "Constants", but I like your way
better. It sounds like modules are more suited to the purpose, being
old and uninstantiatable.

So within my namespace, I just define a module called "Constants" to
contain the CONST declarations. That way, my precious magic numbers
can be referenced like this...

myNameSpace.Constants.mySpecialConstant

Great! And so moderne. Would you believe the database is so old, it
gets B-Dos errors?

Start-to-Finish Visual Basic 2005

Added to my Amazon Wish-List. Is it still on schedule for Nov 15th
release?

Did you actually write the editorial information on Amazon? If the book
is half as lively as that joyful rant, it will be a great addition to
the old bookshelf. I'll put it next to the Petroutsos.


Thank-you so much for wading through the silliness.

Love, PC
 
T

Tim Patrick

It didn't occur to me, but VB constants are indeed objects. Things
like MY_SPECIAL_CONSTANT.AsString are happily accepted. Being an
elderly one, I want to use constants in the same way that one might
have used DEFINEd macro constants in C, i.e. as simple value
substitutes. The presumed overhead of the objectivity seems like a
shame, but there it is.

Of course, one could argue that "Const" statements are also
declarations. Not allowing constants in a namespace still strikes me
as an oversight.

There isn't really a preprocessor in VB like you have in traditional C and
its relatives. Allowing constants to be real objects lets you use strong
data typing with them, something that is essential when you have Option Strict
enabled (an absolute must in my mind). Still, Enums are strongly typed and
they exist at the namespace level, so I can see your point.
So within my namespace, I just define a module called "Constants" to
contain the CONST declarations. That way, my precious magic numbers
can be referenced like this...

myNameSpace.Constants.mySpecialConstant

Actually, everything in your module is global to your application by default,
so you can just refer to them by their unqualified name.

mySpecialConstant
Added to my Amazon Wish-List. Is it still on schedule for Nov 15th
release?

That's what I hear from the publisher, although authors are always the last
to know. Thank you for considering this book.
Did you actually write the editorial information on Amazon? If the
book is half as lively as that joyful rant, it will be a great
addition to the old bookshelf. I'll put it next to the Petroutsos.

Yes, that content is from the book's preface. If you want to read Chapter
1, try this link, which another alert reader listed on this newsgroup earlier.


http://www.codeproject.com/books/StarttoFinishVB2005.asp
 
T

Theo Verweij

Actually, Const is a simple value substitute.

And because you can use 10.tostring, you can also use My_Ten_Const.tostring.

The only part of constants that is new, is the possibility to assign a
type to the constant, so the compiler is able to check if the
substitutions are possible in your constructs - causing compiletime
failures instead of runtime failures.
 
T

Theo Verweij

Proof that consts are really substitutions:

The code:
Module Module1
Public Sub main()
MsgBox("My Message")
End Sub
End Module

Generates the following IL:
..method public static void main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() =
( 01 00 00 00 )
// Code size 16 (0x10)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "My Message"
IL_0006: ldc.i4.0
IL_0007: ldnull
IL_0008: call valuetype
[Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxResult
[Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::MsgBox(object,


valuetype
[Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxStyle,


object)
IL_000d: pop
IL_000e: nop
IL_000f: ret
} // end of method Module1::main

And the code:
Module Module1
Public Const MyMessage As String = "My Message"
Public Sub main()
MsgBox(MyMessage)
End Sub
End Module

Generates this IL
..method public static void main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() =
( 01 00 00 00 )
// Code size 16 (0x10)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "My Message"
IL_0006: ldc.i4.0
IL_0007: ldnull
IL_0008: call valuetype
[Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxResult
[Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::MsgBox(object,


valuetype
[Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxStyle,


object)
IL_000d: pop
IL_000e: nop
IL_000f: ret
} // end of method Module1::main

As you can see, the resulting IL is completely the same.
 
P

PC

Theo said:
Proof that consts are really substitutions:

<Code examples omitted>

As you can see, the resulting IL is completely the same.


Nicely done! Being a V-B New-B, grokking MIL is a bit down on the TODO:
list, but it's great to see something explained at that level.


Love, PC
 

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