Public constant member declared with Const

ID

vbnet.maintainability.no_public_const_member

Severity

high

Remediation Complexity

trivial

Remediation Risk

medium

Remediation Effort

low

Resource

Api Design

Language

VB.NET

Description

Reports a Public Const member of a class, structure or module, whether the type is stated with As or inferred from the initializer. Constants declared Private, Friend or Protected, local constants inside a method, and Public Shared ReadOnly fields - the form this rule asks for - are not reported.

Rationale

A Const is resolved by the compiler, not at run time: every assembly that reads HttpClientOptions.MaxRetries gets the literal 3 copied into its own code, and no reference to the declaring member survives in the compiled output. Publishing one therefore publishes the value rather than the member. Change it to 5 and rebuild only the declaring assembly, and callers that were compiled earlier keep using 3 while the declaring code uses 5 - the same named constant now has two values in one running process, with nothing in either source file to explain it, and the bug typically appears as sizes or limits disagreeing between components. The problem is not theoretical: partial rebuilds are what incremental builds, plugin models and NuGet consumers do by default. A Public Shared ReadOnly field is read through the field at run time, so updating the declaring assembly updates every caller with no rebuild, and it lifts the other restrictions of Const as well - the value may be any type, and may be computed in a shared constructor rather than being limited to a compile-time literal.

The following code illustrates the pattern detected by this rule:

Public Class HttpClientOptions

    ' FLAGGED: Public constant member declared with Const
    Public Const MaxRetries As Integer = 3

    ' FLAGGED: Public constant member declared with Const
    Public Const DefaultUserAgent = "Acme/1.0"

Remediation

Declare the member Public Shared ReadOnly and initialise it in the declaration or in a shared constructor, so callers read the current value at run time. Keep Const for values that are genuinely fixed forever and are not part of the published surface - declare those Private or Friend - and for local constants inside a method, where no other assembly can see them.

' Before: the literal 3 is copied into every calling assembly at compile time
Public Const MaxRetries As Integer = 3

' After
Public Shared ReadOnly MaxRetries As Integer = 3

Configuration

This detector does not need any configuration.