Library tutorials & articles

New Object-Oriented Capabilities in VB.NET

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.

Comments

  1. 01 Jan 1999 at 00:00

    This thread is for discussions of New Object-Oriented Capabilities in VB.NET.

  2. 01 Nov 2002 at 06:35

    If you set a shared property of a user class in a ASP.NET application, how long wil the value last? Application level? Session level? Page level? Well i was actually looking for an answer to that when i got here...  useful article anyway even though it doesn't answer my question...

  3. 21 Nov 2002 at 04:46

    I need a global variable; but it is a "XmlDocument" object, does anybody know how do I have to create it, and how to initialitze it?

  4. 24 Feb 2003 at 08:50
    boig,

    I needed the same thing and found that I have it working using the Public Shared declaration on the class that contains my XMLDocument and the functions to access the document.  This makes the class available across the application.

    Public Shared  oTriggers As Triggers

    If you only need the XMLDocument I would give that a try.

    Hope this helps.
  5. 02 Jul 2003 at 03:14

    How do we read the attributes in an XML file using a DataSet?

  6. 19 Mar 2004 at 16:06
    Error in the article "New Object-Oriented Capabilities in VB.NET - Events"

    Derived classes cannot raise base class events in VB.Net. Handle them sure, but not raise them - even if they are declared public. In order to achieve this handle the base class event and raise a derived class event instead.

    B.
  7. 04 Nov 2004 at 12:10

    Quote:
    [1]Posted by bsol on 19 Mar 2004 04:06 PM[/1]
    Error in the article "New Object-Oriented Capabilities in VB.NET - Events"


    Derived classes cannot raise base class events in VB.Net. Handle them sure, but not raise them - even if they are declared public. In order to achieve this handle the base class event and raise a derived class event instead.


    B.



    While it is true that VB.NET cannot directly raise events in base classes from a derived class, there is an easy workaround. BTW, in C# you can simply call an event in a base class like: base.onMyEventName(EventArgs e).


    But in VB.NET you cannot use MyBase.EventName() at all. But the workaround is an easy one.
    1) In the base class add an overridable sub that simply raises an event defined in the base class.



    Public MustInherit Class MyClass


     Protected Event MyEventName(ByVal e as EventArgs)


     Protected Overridable Sub OnMyEventName(ByVal e as EventArgs)
         Raiseevent MyEventName(e)
     End Sub


    End Class


    2) In the derived class make a call to the overridable method: Me.OnMyEventName(New EventArgs). It's really just that easy. Do it all the time.


    Have Fun....

  8. 12 May 2005 at 01:06
    application level
  9. 22 Feb 2010 at 08:07

    this article is very helpful Thanks Link Text

  10. 23 Jul 2010 at 17:29

    Thank you very much, it help me a lot.

Leave a comment

Sign in or Join us (it's free).

Wrox Press

Related podcasts

  • python411: Language Comparisons

    Published 1 year ago, running time 0h31m

    Comparing Python to Ruby, Perl, Java, C#, VB.Net, C, C++, JavaScript, PHP etc. c, language, python, ruby

Want to stay in touch with what's going on? Follow us on twitter or Facebook!