VB.NET Module member default Public vs Class default Private — controlling implicit visibility
0 reputation · 29 Jan 2021, 21:32 UTC
0 reputation · 29 Jan 2021, 21:32 UTC
VB.NET applies three distinct default accessibility rules: Class and Structure members default to Private, Module and Enum members default to Public, while Interface, Delegate, and top-level Enum declarations default to Friend. This asymmetry is by design for VB6 compatibility, but it creates a silent exposure risk when developers move helper members between a Class and a Module without adding explicit modifiers.
The compiler emits no diagnostic for implicit Public members in a Module, even with Option Strict On. No project-level pragma, /nowarn switch, or .editorconfig rule exists to flip the Module member default to Private or to warn on missing accessibility keywords. Source generators or Roslyn analyzers can surface the issue, but they are opt-in and not part of the standard build.
Partial definitions do not unify the defaults: a member without a modifier in a Partial Class file remains Private, while the same omission in a Partial Module file becomes Public. This means a single logical type split across files can have inconsistent visibility depending on which file a member is declared in.
How can a team enforce explicit accessibility on all Module members without relying on external analyzers? Is there a supported pattern to make Module default visibility match Class behavior at the language or project level? What are the implications for InternalsVisibleTo when a Module’s implicit Public members become visible to friend assemblies?
A thoughtful contribution can make all the difference. Be the first to share one.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.