Search - Articles - Dev Forums - Favorites - Member Login  
DevASP.NET for ASP.NET, VB.NET, XML and C# (C-Sharp) Developers Friday, September 03, 2010

Dev Articles
Search Directory
ASP.NET
VB.Net
C-Sharp
SQL Server
 

Shared Methods, Variables, and Events


So far, all of the methods we've built or used have been instance methods – methods that require us to have an actual instance of the class before they can be called. These methods have used instance variables or member variables to do their work – meaning that they have been working with a set of data that is unique to each individual object.

 

VB.NET allows us to create variables and methods that belong to the class rather than to any specific object. Another way to say this is that these variables and methods belong to all objects of a given class and are shared across all the instances of the class.

We can use the Shared keyword to indicate which variables and methods belong to the class rather than to specific objects. For instance, we may be interested in knowing the total number of Person objects created as our application is running – kind of a statistical counter.

Shared Variables

Since regular variables are unique to each individual Person object, they don't allow us to easily track the total number of Person objects ever created. However, if we had a variable that had a common value across all instances of the Person class, we could use that as a counter. Add the following variable declaration to our Person class:

 

Public Class Person

Implements IDisposable

 

Private Shared sintCounter As Integer

 

By using the Shared keyword, we are indicating that this variable's value should be shared across all Person objects within our application. This means that if one Person object makes the value be 42, all other Person objects will see the value as 42 – it is a shared piece of data.

 

We are using the letter "s" as a prefix to this variable rather than "m". The letter "m" is commonly used for member variables (or module variables), but this variable is not a member variable – it is a shared variable. Using a different prefix can help distinguish between member and shared variables within our code.

 

We can now use this variable within our code. For instance, we can add code to the constructor method, New, to increment the variable so it acts as a counter – adding 1 each time a new Person object is created. Change the New methods as shown:

 

Public Sub New()

Phone("home") = "555-1234"

Phone("work") = "555-5678"

sintCounter += 1

End Sub

 

Public Sub New(ByVal Name As String, ByVal BirthDate As Date)

mstrName = Name

mdtBirthDate = BirthDate

 

Phone("home") = "555-1234"

Phone("work") = "555-5678"

sintCounter += 1

End Sub

 

The sintCounter variable will now maintain a value indicating the total number of Person objects created during the life of our application. We may want to add a property routine to allow access to this value by writing the following code:

 

Public ReadOnly Property PersonCount() As Integer

Get

Return sintCounter

 

End Get

End Property

 

Notice that we're creating a regular property that returns the value of a shared variable. This is perfectly acceptable. As we'll see shortly, we could also choose to create a shared property to return the value.

 

Now we could write code to use our class as follows:

 

Dim myPerson As Person

 

myPerson = New Person()

myPerson = New Person()

myPerson = New Person()

 

MsgBox(myPerson.PersonCount)

 

The resulting display would show 3 – since we've created three instances of the Person class.

Shared Methods

We cannot only share variables across all instances of our class, but we can also share methods. Where a regular method or property belongs to each specific object, a shared method or property is common across all instances of the class.

 

There are a couple of ramifications to this approach.

 

First off, since shared methods don't belong to any specific object, they can't access any instance variables from any objects. The only variables available for use within a shared method are shared variables, parameters passed into the method, or variables declared locally within the method itself. If we attempt to access an instance variable within a shared method, we'll get a compiler error.

 

Also, since shared methods are actually part of the class rather than any object, we can write code to call them directly from the class – without having to create an instance of the class first.

 

For instance, a regular instance method is invoked from an object:

 

Dim myPerson As New Person()

 

myPerson.Walk(42)

 

but a shared method can be invoked directly from the class itself:

 

Person.SharedMethod()

 

This saves the effort of creating an object just to invoke a method, and can be very appropriate for methods that act on shared variables, or methods that act only on values passed in via parameters. We can also invoke a shared method from an object just like a regular method. Shared methods are flexible in that they can be called with or without creating an instance of the class first.


To create a shared method we again use the Shared keyword. For instance, the PersonCount property we created earlier could easily be changed to be a shared method instead:

 

Public Shared ReadOnly Property PersonCount() As Integer

Get

Return sintCounter

End Get

End Property

 

Since this property returns the value of a shared variable, it is perfectly acceptable for it to be implemented as a shared method. With this change, we can now find out how many Person objects have ever been created without having to actually create a Person object first:

 

MsgBox(Person.PersonCount)

 

As another example, in our Person class we could create a method that compares the ages of two people. Add a shared method with the following code:

 

Public Shared Function CompareAge(ByVal Person1 As Person, _

ByVal Person2 As Person) As Boolean

 

Return Person1.Age > Person2.Age

 

End Function

 

This method simply accepts two parameters – each a Person – and returns True if the first is older than the second. The use of the Shared keyword indicates that this method doesn't require a specific instance of the Person class for us to use it.

 

Within this code, we are invoking the Age property on two separate objects – the objects passed as parameters to the method. It is important to recognize that we're not directly using any instance variables within the method, but rather are accepting two objects as parameters and are invoking methods on those objects.

 

To use this method, we can call it directly from the class:

 

If Person.CompareAge(myPerson1, myPerson2) Then

 

Alternately, we can also invoke it from any Person object:

 

Dim myPerson As New Person()

 

If myPerson.CompareAge(myPerson, myPerson2) Then

 

Either way, we're invoking the same shared method and we'll get the same behavior whether we call it from the class or a specific instance of the class.


 

Shared Properties

As with other types of methods, we can also have shared property methods. Properties follow the same rules as regular methods – they can interact with shared variables, but not member variables, and they can invoke other shared methods or properties, but can't invoke instance methods without first creating an instance of the class.

 

We can add a shared property to our Person class with the following code:

 

Public Shared ReadOnly Property RetirementAge() As Integer

Get

Return 62

End Get

End Property

 

This simply adds a property to our class that indicates the global retirement age for all people. To use this value, we can simply access it directly from the class:

 

MsgBox(Person.RetirementAge)

 

Alternately, we can also access it from any Person object:

 

Dim myPerson As New Person()

 

MsgBox(myPerson.RetirementAge)

 

Either way, we're invoking the same shared property.

Shared Events

As with other interface elements, events can also be marked as Shared. For instance, we could declare a shared event in the Person class such as:

 

Public Shared Event NewPerson()

 

Shared events can be raised from both instance methods and shared methods. Regular events can not be raised by shared methods. Since shared events can be raised by regular methods, we can raise this one from the constructors in the Person class:

 

Public Sub New()

Phone("home") = "555-1234"

Phone("work") = "555-5678"

sintCounter += 1

RaiseEvent NewPerson()

End Sub

 

Public Sub New(ByVal Name As String, ByVal BirthDate As Date)

mstrName = Name

mdtBirthDate = BirthDate

 

Phone("home") = "555-1234"


 

Phone("work") = "555-5678"

sintCounter += 1

RaiseEvent NewPerson()

End Sub

 

The interesting thing about receiving shared events is that we can get them from either an object, like a normal event, or from the class itself. For instance, we can use the AddHandler method in our form's code to catch this event directly from the Person class.

 

First let's add a method to the form to handle the event:

 

Private Sub OnNewPerson()

MsgBox("new person " & Person.PersonCount)

End Sub

 

Then, in the form's Load event, add a statement to link the event to this method:

 

Private Sub Form1_Load(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles MyBase.Load

 

AddHandler Person.NewPerson, AddressOf OnNewPerson

 

mobjPerson = New Person()

If Microsoft.VisualBasic.Command = "nodisplay" Then

AddHandler mobjPerson.Walked, AddressOf LogOnWalk

Else

AddHandler mobjPerson.Walked, AddressOf OnWalk

End If

End Sub

 

Notice that we are using the class rather than any specific object in the AddHandler statement. We could use an object as well – treating this like a normal event, but this illustrates how a class itself can raise an event.

 

When we run the application now, any time a Person object is created we'll see this event raised.



DevASP.Net - Disclaimer - Privacy
© 2002-2010 DevASP.net