views:

75

answers:

3

VB.NET (.NET 2)

Say I have some constants that depends one of other, 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 compiler force 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?

A: 

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
hm... a little bit strange Enum usage. Do you think the readability of code will not suffer?
serhio
and after all, I will be forced to convert every time from Enum to int... not very convenient.
serhio
IMO enum won't be better option. Consider having two constants with different names/meanings, but same values.
Yossarian
+5  A: 

Since it's VB.Net, if they are truly global constants and their name by themself 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.

ho1
no, that values are private constants, at least, it should not be modified from outside...
serhio
unfortunately a `Module` can't be created inside a class... What is the avantage of ReadOnly vs Constant?
serhio
@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
ho1
@ho1: 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
@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.
ho1
+3  A: 

In my opinion the best Option for this purpose is to create a (private) class with only shared/static members/constants. You dont 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

EDIT: added NotInheritable to the class because it is what the compiler would produce as IL when you use a Module. I prefer a "standard-Dot.Net"-way over the VB-only stuff. Besides you have more control over its accessibility and you can make it as innerclass. This is in fact the VB.Net pendant to a C# static class.

Tim Schmelter
see my comment on the main thread. I will need to create instances.
serhio
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
@Tim: It's impossible to create a Shared Class in VB.NET.
serhio
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
I think I began to understand your idea. private new... ok ok.
serhio
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