Shared (Visual Basic)
Specifies that one or more declared programming elements are associated with a class or structure at large, and not with a specific instance of the class or structure.
When to Use Shared
Sharing a member of a class or structure makes it available to every instance, rather than nonshared, where each instance keeps its own copy. This is useful, for example, if the value of a variable applies to the entire application. If you declare that variable to be Shared, then all instances access the same storage location, and if one instance changes the variable's value, all instances access the updated value.
Sharing does not alter the access level of a member. For example, a class member can be shared and private (accessible only from within the class), or nonshared and public. For more information, see Access Levels in Visual Basic.
Rules
Declaration Context. You can use Shared only at module level. This means the declaration context for a Shared element must be a class or structure, and cannot be a source file, namespace, or procedure.
Combined Modifiers. You cannot specify Shared together with Overrides (Visual Basic), Overridable (Visual Basic), NotOverridable (Visual Basic), MustOverride (Visual Basic), or Static (Visual Basic) in the same declaration.
Accessing. You access a shared element by qualifying it with its class or structure name, not with the variable name of a specific instance of its class or structure. You do not even have to create an instance of a class or structure to access its shared members.
The following example calls the shared procedure IsNaN exposed by the Double structure.
If Double.IsNaN(result) Then MsgBox("Result is mathematically undefined.")
Implicit Sharing. You cannot use the Shared modifier in a Const Statement (Visual Basic), but constants are implicitly shared. Similarly, you cannot declare a member of a module or an interface to be Shared, but they are implicitly shared.
Behavior
Storage. A shared variable or event is stored in memory only once, no matter how many or few instances you create of its class or structure. Similarly, a shared procedure or property holds only one set of local variables.
Accessing through an Instance Variable. It is possible to access a shared element by qualifying it with the name of a variable that contains a specific instance of its class or structure. Although this usually works as expected, the compiler generates a warning message and makes the access through the class or structure name instead of the variable.
Accessing through an Instance Expression. If you access a shared element through an expression that returns an instance of its class or structure, the compiler makes the access through the class or structure name instead of evaluating the expression. This produces unexpected results if you intended the expression to perform other actions as well as returning the instance. The following example illustrates this.
Sub main() shareTotal.total = 10 ' The preceding line is the preferred way to access total. Dim instanceVar As New shareTotal instanceVar.total += 100 ' The preceding line generates a compiler warning message and ' accesses total through class shareTotal instead of through ' the variable instanceVar. This works as expected and adds ' 100 to total. returnClass().total += 1000 ' The preceding line generates a compiler warning message and ' accesses total through class shareTotal instead of calling ' returnClass(). This adds 1000 to total but does not work as ' expected, because the MsgBox in returnClass() does not run. MsgBox("Value of total is " & CStr(shareTotal.total)) End Sub Public Function returnClass() As shareTotal MsgBox("Function returnClass() called") Return New shareTotal End Function Public Class shareTotal Public Shared total As Integer End Class
In the preceding example, the compiler generates a warning message both times the code accesses the shared variable total through an instance. In each case it makes the access directly through the class shareTotal and does not make use of any instance. In the case of the intended call to the procedure returnClass, this means it does not even generate a call to returnClass, so the additional action of displaying "Function returnClass() called" is not performed.
The Shared modifier can be used in these contexts: