I'm reminded of the old programmer joke, "There are 10 kinds of programmers. Those who understand binary and those who don't."
In a similar way, there are 10 kinds of class members in VB.NET. Shared members and instance members. There are also shared variables and shared events. These are covered in different articles:/p>
But before we get into that, let's review the whole concept of classes and a class members. A class is the code for an object. Classes are really just collections of methods and properties that are bundled together for your convenience in using them. These methods and properties are collectively called the class members.
The completely expanded code for a property in a class used to look something like this:
Public Property aSampleProperty() As datatype Get ' code to retrieve the property Return property value End Get Set(ByVal value As datatype) ' code to initialize or update the property End Set End Property
(This was changed in VB.NET 2010. The compiler now adds the getter and setter - Get and Set statement blocks - for you in the compiled code so you don't have to. But it's good to know what is still going on behind the scenes, especially since there are still some cases where you have to code your own getter and setter.)
And the code for a method might look like this:
Public Sub aSampleMethodSub( ByVal or ByRef aParameter As datatype) ' method code End Sub
Public Function aSampleMethodFunc( ByVal aParameter As datatype ) As datatype ' method code aSampleMethodFunc = ReturnValue End Function
After an object (that is, the compiled class code) is included in your project, you normally have to create an instance of the the object to use the members, something like this:
Dim myInstance as New aSampleObject
You can then use the methods and properties of the object:
myInstance.aSampleProperty = myVariable myInstance.aSampleMethodSub(myVariable) anotherVariable = myVariable oneMoreVariable = myInstance.aSampleMethodFunc(myVariable)
These types of members are called "instance members" because you have to create an instance, a copy of the object exclusively for your code, to use the members. This is the most common code that you'll see and write when you code your own classes.
One way to prove to yourself that you're using a copy would be to code a method that contains a property and then change the property in copies of the object. For example code these members and in the class:
Private m_Property As Integer Public ReadOnly Property testProperty() As String Get Return m_Property End Get End Property Public Sub TestMethod(ByVal Selector As Boolean) If Selector = True Then _ m_Property = 99999 _ Else _ m_Property = 11111 End Sub
Then create two instances of the same class in the calling code:
Dim myInstance = New testClass Dim anotherInstance = New testClass
Then set the value of the m_Property to different values in each of them and check them out:
myInstance.TestMethod(True) anotherInstance.TestMethod(False) MsgBox(myInstance.testProperty) MsgBox(anotherInstance.testProperty)
Each instance of the object now contains a different property value.
The second type of member that an objects can have is called a shared member. The syntax for shared members is different. In particular, you don't have to create an instance of the object in your code to use a shared member. One of the best examples of shared methods can be found in the Math class that is part of the .NET Framework. Enter Math. in the VB.NET editor to see all of the methods and properties available. To take advantage of shared properties and methods, just code the object and the member directly. For example, to get the trigonometric tangent of a 45 degree angle:
MsgBox(Math.Tan((Math.PI / 180) * 45))
This give you the value 1. Note that the Math object trig functions have to be expressed in radians so both the shared property PI, to convert from degrees to radians, and the shared method Tan had to be used.
A major reason for using a shared member rather than an instance member is to avoid having to code a member for every class that might use essentially the same one. For example, the Format method of the String object is a shared method that you see a lot. Using this method, you can format a wide variety of data types such as dates and times, numbers and strings.
Dim aDate As Date = #12/7/1941# Console.WriteLine(Format(aDate, "MMM dd, yyyy")) Dim aNum As Double = 123.4567 Console.WriteLine(Format(aNum, "##0.00"))
If Format was an instance method, it would have to be defined for every type instead. In other words, The DateTime type would have to have a Format method defined for it and the Double type would have another one. Then you could code something like:
' This doesn't work - example only Dim aDate As Date = #12/7/1941# Console.WriteLine(aDate.Format(#12/7/1941#)) Dim aNum As Double = 123.4567 Console.WriteLine(aNum.Format("##0.00"))
Shared properties are much less common than shared methods and it's not likely that you'll code very many in your own programs. The reason is that there are usually no constant values that are always the same whenever an object is used. One classic example of a shared property is the collection of connection parameters for a database when the code for an object needs to query a database. Since they're usually constant, these connection parameters for the call are often shared properties.
Here's a simplified example of a class that uses both shared properties and methods.
Suppose you had a class that was used to query an inventory database. A common requirement for the class would probably be to return the current inventory. This method doesn't require any parameters and would be the same for all programs. Note that the qualifications for the Function statement are the major difference.
Public Shared Function CurrentInventory() As Integer ' A database call would probably be ' coded in this method. ' For our purposes, we'll stub ' the method with a constant value. CurrentInventory = 12345 End Function
An example of a system that uses a shared property might be a system that normally uses inventory contained in a specific database. The database used could be enforced by coding the name as a shared property. (There are other ways to solve this problem too and I'm not claiming this is the best one.) One advantage (or disadvantage, since it falls into a category of a "hidden" function of the program) is that the database actually used depends on the version of the object library included. Different versions could reference different databases. One might include one database with phony numbers to generate a report for the auditors and another for owners. I'm not suggesting that you should of course, since that would be illegal:
Public Shared ReadOnly Property DBName() As String Get Return "FunnyNumbers_DB_for_the_auditors" End Get End Property
You can reference the properties and methods for this custom object just like the ones in the .NET Framework:
It's just like you learned as a child, "It's good to share."