Shared or Class Members
While
objects are very powerful and useful, there are times when we just want access
to variables, functions, or routines that do useful work – without the need
for an actual object instance. In the past, we would typically put this type
of code into a simple code module even if the routine was technically related
to some class.
Shared Methods
In VB.NET we have a better
alternative. Not only can a class have all the regular methods and properties
we’ve seen so far – methods and properties only available after creating an
instance of the class – but they can also have methods that are available without
creating an instance of the class. These are known as shared methods.
These methods are also known as static methods or class methods
in other languages.
A shared method is not accessed via an
object instance like a regular method, but rather is accessed directly from
the class. The following is a simple example of a shared method:
Public Class Math
Shared Function Add(ByVal
a As Integer, ByVal b As Integer) As Integer
Return
a + b
End Function
End Class
We can use this method – without instantiating
a Math
object – as follows:
Dim result As Integer
result = Math.Add(5,
10)
Notice how, rather than using an object
variable, we use the actual class name to reference the method. With a normal
method this would result in a syntax error, but with a shared method this is
perfectly acceptable.
Shared methods can also be accessed via
objects just like regular methods, but their most common use is to provide functionality
without the requirement for creating an object.
In fact, when a shared method is invoked, no object
is created – the method is called directly, much like a procedure in a Module.
Shared methods can also be overloaded
just like regular methods, so it is quite possible to create a set of variations
on the same shared method, each having a different parameter list.
The default scope for a shared method
is Public.
It is possible to restrict the scope of a shared method to Friend,
Protected,
or Private
by prefixing the declaration with the appropriate scope. In fact, when overloading
a method we can have different scopes on each implementation – as long as the
parameter lists are different as we discussed when covering the Overloads
keyword earlier.
A good example of how shared methods are
used comes from the .NET system class libraries. When we want to open a text
file for input we typically make use of a shared method on the File
class:
Dim infile As StreamReader
= File.OpenText(“words.txt”)
Dim strIn As String
str = infile.ReadLine()
No object of type File
is created here. The OpenText
method is a shared method that opens a file and returns a StreamReader
object for our use. Another example comes from the System.Guid
data type. This class represents a globally unique identifier (GUID) value,
but creating a new value is handled via a shared method:
Dim guidID As Guid()
guidID = Guid.NewGuid()
The NewGuid method is called directly from the Guid class. It creates a new Guid
object and returns it as a result.
Shared Variables
There
is another type of shared member we can create. There are times when it is nice
to share a value across all instances of a class – when every object of a given
type should share the same variable. This is accomplished through the use of
shared
variables.
A shared variable is declared using the
Shared
keyword, much like a shared method:
Public Class MyCounter
Private Shared mintCount
As Integer
End Class
As with shared methods, we can scope the
shared variable as required.
Where Shared
methods are Public
by default, Shared
variables are Private
by default.
In general, it is good practice
to always explicitly define the scope of methods and variables to avoid confusion.
The important thing about shared variables
is that they are common across all instances of the class. We could enhance
our class slightly as follows:
Public Class MyCounter
Private Shared mintCount
As Integer
Public Sub New()
mintCount
+= 1
End Sub
Public ReadOnly Property
Count() As Integer
Get
Return
mintCount
End Get
End Property
End Class
As we create each instance of the class
the counter is incremented by one.
The +=
operator is new to VB.NET and is covered in Chapter 3.
At any point, we can retrieve the count
value via the Count property.
Thus, if we run the following client code we’ll get a resulting value of 3:
Protected
Sub Button4_Click(ByVal
sender As Object, _
ByVal e As System.EventArgs)
Dim obj As MyCounter
obj = New MyCounter()
obj = New MyCounter()
obj = New MyCounter()
MsgBox(obj.Count, MsgBoxStyle.Information, “Counter”)
End
Sub
If we run it again we’ll get 6,
then 9,
and so forth. As long as our application is running the counter will remain
valid. Once our application terminates the counter also goes away.
This technique can be very useful for
server processes that run “forever” since they can keep usage counters or other
values over time very easily. The values are only reset when the process is
restarted.
Global Values
Another common use
for shared variables is to provide a form of global variable. Given a Public
scoped shared variable:
Public Class TheClass
Public Shared MyGlobal
As Integer
End Class
We can then use this variable throughout
our client code:
TheClass.MyGlobal +=
5
This variable will be available to any
code within our application, providing a very nice mechanism for sharing values
between components, classes, modules, and so forth.