0
    Private Const TOKEN_LENGTH As Integer = 8 ' this may come from app.config at startup
    Private Const TOKEN_MIN As Integer = 10 ^ (TOKEN_LENGTH - 1)
    Private Const TOKEN_MAX As Integer = 10 ^ TOKEN_LENGTH - 1

    'how do I make TOKEN_FORMAT a CONST?
    Private Const TOKEN_FORMAT As String = "0".PadRight(TOKEN_LENGTH)

    'sample usage
    Dim TokenCode As String = New Random().Next(TOKEN_MIN, TOKEN_MAX).ToString(TOKEN_FORMAT)

The following code gives this error: Constant expression is required.

Private Const TOKEN_FORMAT As String = "0".PadRight(TOKEN_LENGTH)

Once defined, TOKEN_FORMAT will never change, its definition simply depends on another constant TOKEN_LENGTH. so why cant it also be compile-time evaluated?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Charles Okwuagwu
  • 10,538
  • 16
  • 87
  • 157
  • A constant has to be constant, which means being known at compile time. Your value is not known until run time so is therefore not constant. A read-only field is the best you can do in that case. Do you really need both values as constants anyway? Exactly how will they be used? Could you not simply define the `String` as a constant and then determine its `Length` at run time on an as-needed basis? – jmcilhinney Aug 17 '14 at 04:42
  • @jmcilhinney so how come this is valid: Private Const TOKEN2 As Integer = TOKEN_LENGHT *100 ? i dont "know" TOKEN_LENGHT until runtime – Charles Okwuagwu Aug 17 '14 at 05:46
  • When you declare a constant, the value you assign must be a literal, another constant or some fundamental combination of literals and/or constants. `TOKEN_LENGTH * 100` is a fundamental combination of another constant and a literal, so its value is known absolutely at compile time. Any expression that calls a method is not valid because who knows what is inside that method? It could try to connect to a database for all we know, which is obviously not possible at compile time. – jmcilhinney Aug 17 '14 at 06:44

2 Answers2

1

You're trying to get too fancy. These are constants so give them constant values. Your TOKEN_LENGTH constant is pointless.

Const TOKEN_FORMAT As String = "00000000"
Const TOKEN_MIN As Integer = 10000000
Const TOKEN_MAX As Integer = 99999999

That's all you need.

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
0

Better in what way you needed? How about property without setter, for example :

Public Class ConstantTest
    Private Const TOKEN_LENGTH As Integer = 6
    Private ReadOnly Property TOKEN_FORMAT() As String
        Get
            Return "0".PadRight(TOKEN_LENGTH, "0"c)
        End Get
    End Property
    Private ReadOnly ANOTHER_TOKEN_FORMAT As String = "0".PadRight(TOKEN_LENGTH, "0"c)

    Public Sub New()
        'you can change readonly field in constructor...'
        ANOTHER_TOKEN_FORMAT = "test"
        'but setting "get-only" property is not allowed even in constructor'
        TOKEN_FORMAT = "test"   '<- compile error here'
    End Sub
End Class

You can change value of readonly field in constructor which make it less similar to Const, but the same trick can't be applied to a property without setter as demonstrated in above example.

Related discussions : const vs. readonly, What is the difference between const and readonly?

Community
  • 1
  • 1
har07
  • 88,338
  • 12
  • 84
  • 137
  • better in the sense that constants are compile time evaluated. once defined, TOKEN_FORMAT will never change, its definition simply depends on another constant TOKEN_LENGTH. so why cant it also be compile-time evaluated? – Charles Okwuagwu Aug 17 '14 at 06:02