2

Say I have some constants that depends on one another, and I decided to keep them together in a container instead of keeping it as individual constants in a class.

I thought use a Structure for that scope, but the compiler forces me to declare a private member for that structure.

  ' Compile error: at least one private member is needed.
  Private Structure BandSizes 
    Const BandHeight As Short = HourHeight + 20
    Const HourHeight As Short = HalfHourHeight + 20
    Const HalfHourHeight As Short = LineHeight + PictureHeight + 20
    Const PictureHeight As Short = 20
    Const LineHeight As Short = StopHeight + 10
    Const LineWidth As Short = 50
    Const StopHeight As Short = 30
  End Structure

As I have only a few integer constants, should I create a shared (static) class?

Platform: VB.NET (.NET 2)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
serhio
  • 28,010
  • 62
  • 221
  • 374
  • 1
    I don't get it, why do you want to store the constants in an structure and not in a class? – Dejan Jun 29 '10 at 10:38
  • 1
    A class is reference type but a structure is value type. And I don't want to create instances of that class, neither I can create a Shared Class in VB... – serhio Jun 29 '10 at 10:55

4 Answers4

9

In my opinion, the best option for this purpose is to create a (private) class with only shared, static members, and constants. You don't need to create an object and you can control accessibility as you want.

   Private NotInheritable Class BandSizes
        Public Const BandHeight As Short = HourHeight + 20
        Public Const HourHeight As Short = HalfHourHeight + 20
        Public Const HalfHourHeight As Short = LineHeight + PictureHeight + 20
        Public Const PictureHeight As Short = 20
        Public Const LineHeight As Short = StopHeight + 10
        Public Const LineWidth As Short = 50
        Public Const StopHeight As Short = 30

        Private Sub New()
        End Sub
    End Class

Note: NotInheritable is needed in the declaration of the class, because it is what the compiler would produce as CIL when you use a Module. I prefer a "standard-.NET"-way over the Visual Basic-only stuff. Besides, you have more control over its accessibility and you can make it as innerclass. This is in fact the VB.NET counterpart to a C# static class.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • 1
    see my comment on the main thread. I will need to create instances. – serhio Jun 29 '10 at 11:45
  • 3
    Why do you need to create an instance of a shared class?? You can access the constants in the following way: Dim bandHeight As Short = BandSizes.BandHeight. There is no instance of class BandSizes at all. – Tim Schmelter Jun 29 '10 at 11:50
  • 1
    @Tim: It's impossible to create a Shared Class in VB.NET. – serhio Jun 29 '10 at 12:39
  • 2
    In VB.Net there is no static/shared class like in C# but you dont need an instance of it anyway, when every member of the class is shared/const. It is like the VB.Net equivalent of a static class. Try to instatiate my Class, actually you can't ;) – Tim Schmelter Jun 29 '10 at 12:44
  • 1
    I think I began to understand your idea. private new... ok ok. – serhio Jun 29 '10 at 12:50
  • Ok, but you have still concerns? I prefer not to use VB-only-stuff when i can achieve the same on a standard Dot.Net way. No reason to use a module here, because the compiler would generate the same IL as my code produces. – Tim Schmelter Jun 29 '10 at 15:32
6

Since it's VB.NET, if they are truly global constants and their name by themselves is enough, you can also create a Module to keep them in.

Also, be aware that if these constants are accessed from external assemblies there can be issues if the values of these constants can ever change. So if these were public and put in a class library for example it might be better to have them as ReadOnly rather than constant.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
  • 1
    no, that values are private constants, at least, it should not be modified from outside... – serhio Jun 29 '10 at 10:48
  • 1
    unfortunately a `Module` can't be created inside a class... What is the avantage of ReadOnly vs Constant? – serhio Jun 29 '10 at 10:58
  • 1
    @serhio: Sorry, didn't realise that you meant that you wanted to have an internal constants class. Re the ReadOnly vs Constant this question answers it well: http://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly – Hans Olsson Jun 29 '10 at 11:31
  • 1
    I know the difference between Const and Readonly, I wonder of the advantage in this concrete case. I'd leave Const in the module. – serhio Jun 29 '10 at 11:44
  • 1
    @serhio: Yes, if the constants are internal to that class, and there's no chance that they'll later both be changed and be inherited to a class in a different assembly, then I'd keep them as constant. – Hans Olsson Jun 29 '10 at 11:57
  • @tim: thank you for this, i was wondering how this worked, now i use it just to keep my global databaseconnections and settings. – renevdkooi Feb 27 '12 at 11:42
2

Instead of making it "const", I would recommend you to have a look at the article Constants in .NET and then decide that you should use "const" or you should go with "readonly".

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dr. Rajesh Rolen
  • 14,029
  • 41
  • 106
  • 178
-2

An enum might be a better option. Not sure about VB syntax, but C# would be:

internal enum BandSizes {
  BandHeight = HourHeight + 20,
  HourHeight = HalfHourHeight + 20,
  HalfHourHeight = LineHeight + PictureHeight + 20,
  PictureHeight = 20,
  LineHeight = StopHeight + 10,
  LineWidth = 50,
  StopHeight = 30,
}

(NB. if this is an namespace scope, internal is the most restrictive access, but private is possible if a member of a class or structure.)

EDIT: Here's the VB version:

Friend Enum BandSizes
    BandHeight = HourHeight + 20
    HourHeight = HalfHourHeight + 20
    HalfHourHeight = LineHeight + PictureHeight + 20
    PictureHeight = 20
    LineHeight = StopHeight + 10
    LineWidth = 50
    StopHeight = 30
End Enum

Where Friend is the VB for internal (and the same limitation on Private is only possible for type members).

Richard
  • 106,783
  • 21
  • 203
  • 265
  • hm... a little bit strange Enum usage. Do you think the readability of code will not suffer? – serhio Jun 29 '10 at 10:45
  • and after all, I will be forced to convert every time from Enum to int... not very convenient. – serhio Jun 29 '10 at 10:50
  • 2
    IMO enum won't be better option. Consider having two constants with different names/meanings, but same values. – nothrow Jun 29 '10 at 10:52