Static Class Constants (VB 2005)

  • Thread starter Thread starter Michael D. Ober
  • Start date Start date
Hi Cor ,


Maybe my reponse should have been more clear

cause wasn`t this wat you showed , however it looks like this is a
workaround for the TS ( it is not exactly what he wants )

i was only wondering why you did not do this ( maybe i am missing a obvious
reasson )

Public Class myConstantClass

Public Shared ReadOnly Property ConstantString() As String

Get

Return "WhatEverConstantString"

End Get

End Property

End Class


regards

Michel Posseth
 
Ah,

Sorry Michel, I see it now.

I was hoping on a long discussion about saving one bit by doing it not this
way.
Of course just use the string is even better.

:-)))

Cor
 
doh,

again a possibility for misunderstanding
I was hoping on a long discussion about saving one bit by doing it not
this way.

I was hoping on a long discussion about saving one bit by doing it by not
using a read only property but a constant

:-)

Cor
 
Cor,

Cor Ligthert said:
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.
[...]
In my opinion it is what is called a shared class no class but a module.

I agree. I have never liked the idea of "static classes" as available in
C#. Static classes are semantically nonsense. They are no classes, and
they should not be types. They are simply a grouping mechanism which should
be as lightweight as namespaces are. To me it seems that some OOP purists
simply didn't want to use a semantically more correct term such as module,
unit, or group because it's not an OO term.
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)

Exactly true!
 
Cor Ligthert said:
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.

Read-only properties and constants are treated differently by the compiler.
While constants' values are embedded into assemblies using your library at
compile-time, the value of read-only properties is determined at runtime.
Thus it's not necessary to recompile dependent libraries when changing the
return value of a read-only property opposed to a constants.

I use public constants in very few cases only. Often constants are an
implementation detail only.
 
Herfried,
Read-only properties and constants are treated differently by the
compiler. While constants' values are embedded into assemblies using your
library at compile-time, the value of read-only properties is determined
at runtime. Thus it's not necessary to recompile dependent libraries when
changing the return value of a read-only property opposed to a constants.

I use public constants in very few cases only. Often constants are an
implementation detail only.
Exact this answer was what I expected and than I find a read-only property
something nicer.

However are you sure of that assembly part, I did not try it yet, however I
am almost sure that in the way Michel made it, (forgive me my mistake) will
result in the same constant in the ILS. Those strings are immutable you
know?

:-)

Cor
 
I'm working with the interface to a legacy VMS system. Data records are
returned in a string of format "FileChannel & vbNL & RecordData". This
interface can return multiple records per call and each record can
potentially be from a different channel. I need to be able to do the
following:

dim basechannel as somechannel ' SomeChannel is an object that is created
based on the VMS RMS File definition, which I have access to and have a VB 6
cross compiler that generates the .NET VB2005 class object. (RMS allows
overlapping field layouts)

dim haveObjType2 as boolean = false
for each s as string in LegacyInterface.GetData(<VMSChannelStart>,
<lookupcriteria>, <NumberToGet>)
dim channel as string = LegacyInterface.GetChannel(s)
if ChannelType1.Channel = channel and haveObjType2 then
' Process ChannelType1 data only if ChannelType2 data has been found
dim objType1 as new ChannelType1(s)
' Do something with objType1

case ChannelType2.Channel:
dim objType2 as new ChannelType2(s)
haveObjType2 = true
' Do something with it
LegacyInterface.Update(objType2.Channel, objType2.buffer)

case ChannelType3.Channel
' not needed either
end select
next s

Why go through the overhead of creating non-required types. Also, in some
cases, I may have to create objType1 depending on what is returned in
objType2. I didn't design the underlying RMS database structure - it's not
even 1st Normal form. Note that I ALWAYS use Option Strict On and Option
Explicit On. I've had too many experiences where VB 6 didn't pick up a type
cast failure at compile time and the application didn't work as expected. I
want the compiler to tell me when there is a type casting problem.

Here's a sample of the output of the RMS cross compiler:

Option Explicit On
Option Strict On
Option Compare Text
Public Class COMMENT4
' Created with DefToCls v.4.1.10
' Created on #11/11/2005 1:58:33 PM#
' VMS Source File has VBTags
' VMS Source File Header for \\JAGUAR\VMSDEVHOME\def\4COMMENT.DEF
' !
' !TITLE: WA$SOURCE:4COMMENT.DEF
' !
' !22-DEC-95 NSB CREATED NEW DEF
' !31-MAY-96 MVD CHANGE COMMENT_TYPE TO 3 CHAR
' !01-AUG-96 MVD CHANGE COMMENT_TYPE TO 5 CHAR AND MOVE TO KEY
' !07-AUG-96 MVD CHANGE DATE TO 10 CHARACTERS
' !4-MAR-97 NSB ADDED SUB_TYPES VARIANT AND DOCUMENTAION
' !16-JAN-99 NSB MODIFIED TO THE FINAL FORMAT
' !
' ! THE NEW FORMAT
' !
' ! VB_CHANNEL=COMMENT
' ! VB_RECORD_LENGTH=105
' !
' RECORD TYPE$_4COMMENT

Public Const RecSize as Integer = 105

Private buffer As String
Public Sub New()
init
End Sub
Public Sub New(ByVal value As String)
buffer = LSet(value, 105)
End Sub
Public Sub init()
buffer = Space(105)
End Sub

' These two functions are to keep the code later simpler to read
Private Function fetch(ByVal start As Integer, ByVal chars As Integer) As
String
fetch = Mid(buffer, start, chars)
End Function
Private Sub putch(ByRef s As String, ByVal start As Integer, ByVal chars
As Integer)
Mid(buffer, start, chars) = LSet(s, chars)
End Sub

' VAX Channels
Public Const Channel as String = "COMMENT"

'DBServer Key Fields
Public Const VBKey_KEY0 as String = "KEY0"

'Key ACCT_NUM not in .OPN file
Public Const VBKey_ACCT_NUM as String = "ACCT_NUM"

'DBServer Data Fields
Public Property BUF() as String
Get
Return fetch(1, 105)
End Get
Set(ByVal value as string)
putch(value, 1, 105)
End Set
End Property
Public Property KEY0() as String
Get
Return fetch(1, 19)
End Get
Set(ByVal value as string)
putch(value, 1, 19)
End Set
End Property

' Multiple fields cut out - they follow the same code sequence as BUF and
KEY0

'Formatted Print Property
Public Shadows ReadOnly Property ToString(Optional ByVal prefix As String =
"", Optional ByVal indent As Boolean = False) As String
Get
Dim IndentChar As String
If indent Then IndentChar = vbTab Else IndentChar = ""
Dim fp As String = ""
fp &= IndentChar & "KEY0: '" & KEY0 & "'" & vbNewLine
fp &= IndentChar & "OFFICE: '" & OFFICE & "'" & vbNewLine
fp &= IndentChar & "ACCT_NUM: '" & ACCT_NUM & "'" & vbNewLine
fp &= IndentChar & "COMMENT_TYPE: '" & COMMENT_TYPE & "'" &
vbNewLine
fp &= IndentChar & "PRODUCT: '" & PRODUCT & "'" & vbNewLine
fp &= IndentChar & "T_IME: '" & T_IME & "'" & vbNewLine
fp &= IndentChar & "D_ATE: '" & D_ATE & "'" & vbNewLine
fp &= IndentChar & "COLLECTOR: '" & COLLECTOR & "'" & vbNewLine
fp &= IndentChar & "CMMT: '" & CMMT & "'" & vbNewLine
prefix = Trim$(prefix)
If prefix <> "" Then
Dim lines() As String = Split(fp, vbNewLine)
fp = ""
For i As Integer = LBound(lines) To UBound(lines)
If Left(lines(i), Len(IndentChar) + Len(prefix)) =
(IndentChar & prefix) Then fp &= lines(i) & vbNewLine
Next i
End If
Return fp
End Get
End Property

Public Function Clone() As COMMENT4
Return New COMMENT4(buffer)
End Function
End Class

Mike.
 
Beta 2 worked - a public constant could be accessed via the Class Name or
via an Object reference.

Mike.

schneider said:
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]


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.
 
It depends on the optimizer. A read only property that returns a constant
string should be caught and converted to a constant at compile time. A read
only property that computes it's result based on internal object state
cannot be optimized into a single return value.

Mike Ober.
 
Michael D. Ober said:
It depends on the optimizer. A read only property that returns a constant
string should be caught and converted to a constant at compile time. A
read
only property that computes it's result based on internal object state
cannot be optimized into a single return value.

I have to disagree. Converting it to a constant at compile time for the
reasons described in another reply (stronger dependency between multiple
components).
 

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