According to MSDN the Me keyword provides a way to refer to the specific instance of a class or structure in which the code is currently executing. Me behaves like either an object variable or a structure variable referring to the current instance. Using Me is particularly useful for passing information about the currently executing instance of a class or structure to a procedure in another class, structure, or module.
Let’s say that in Visual Basic .Net when you create a form you want to explicitly create the default constructor.
You may be probably doing this to add some extra-initialization to the constructor. Another reason could be to make it obvious that a constructor exists as otherwise a default constructor is provided implicitly and transparently.
Now when you just typed:
Public Sub New()
and pressed Enter, Visual Studio will automatically insert code by adding some comments and a call to
This method is responsible of instantiating all the controls that you placed on the form at design time and many others … so you want to have it called from any other constructors you may end up with. This method would have been called automatically by the default provided constructor.
So, to recap, the default constructor that you just typed, looks like this:
Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. End Sub
Let’s say we need a constructor that takes a parameter. To preserve having InitializeComponent() called but to not have to call it explicitly we call the default constructor from this new one :
Public Sub New(param as String) ‘Calls the parameterless constructor thus InitializeComponent gets called as well Me.New() txtParam.Text = param End Sub
If we need another constructor that take two parameters we do the same only this time we call the constructor that takes one parameter:
Public Sub New(param as String, param2 as String) ‘ same thing; calling the previous constructor to preserve the initialization Me.New(param) txtParam2.Text = param2 End Sub
Again, we avoided duplicating the code that calls the InitializeComponent and some other code the previous parameterized constructor was executing by simply invoking that constructor through the use of the Me keyword.
What about MyClass? Well, with this one it is a bit more complicated.
According to MSDN the MyClass keyword behaves like an object variable referring to the current instance of a class as originally implemented. MyClass is similar to Me, but all method calls on it are treated as if the method were NotOverridable.
One thing for starters is that you would use this keyword in a base class’ code not in the inheritor. Why? Because it offers you a mechanism to write methods in that base class that circumvent polymorphism and guaranties a client a certain original/base functionality even when called from a derived class instance.
Let’s say we have:
Class baseClass Public Sub testMethod() MsgBox("Base class string") End Sub End Class
and we decided we need new functionality for testMethod but we need to preserve the baseClass functionality. We change the testMethod in the base class to Overridable and redefine it in a derived class with Overrides (this will give you the polymorphic behaviour):
Class baseClass Public Overridable Sub testMethod() MsgBox("Base class string") End Sub End Class Class derivedClass : Inherits baseClass Public Overrides Sub testMethod() MsgBox("Derived class string") End Sub End Class
Now, if we instantiate a derivedClass
Dim testObj As derivedClass = New derivedClass() testObj.testMethod()
and we call testMethod we will se the “Derived class string” being displayed. Even if we cast or declare the testObj instance to or as a baseClass, still the overridden method will execute. Even if you define another method on the base class that calls testMethod
Class baseClass Public Overridable Sub testMethod() MsgBox("Base class string") End Sub Public Sub useTestMethod() ‘ The following call uses the calling class's version, ‘ even if that version is an override. Me.testMethod() End Sub End Class
the testMethod that will execute will be the one on the derivedClass (as long as the instance is a derivedClass)
So, how can we get the original testMethod execute on a derivedClass instance. Well, we can try to re-write the base class like this:
Class baseClass Public Overridable Sub testMethod() MsgBox("Base class string") End Sub Public Sub useBaseTestMethod() ' The following call uses this version and not any override. MyClass.testMethod() End Sub End Class
and have the client call useBaseTestMethod instead of testMethod. The difference is that calling testMethod on a derivedClass instance you will get derivedClass functionality but when you call useBaseTestMethod you will get the baseClass original testMethod to execute and only because of the special way of invoking it: prefixed by the MyClass keyword.
So , MyClass allows the designer of a class to say: I want this method call, when it invokes certain other methods of this class, to always invoke whatever implementation (or portion of implementation) I wrote for those in this class and never ever even think of executing the override versions.
Considering the previous example if you would want to create a method in the derivedClass that performs both the functionality from the baseClass and the new one in from the derived class. If the testMethod of the derivedClass changed to:
Class derivedClass Inherits baseClass Public Overrides Sub testMethod() MyBase.testMethod() MsgBox("Derived class string") End Sub End Class
The addition of the MyBase.testMethod() allows us to execute the baseClass functionality first so we get both message boxes displayed. So, if we have the possibility of calling MyBase.testMethod to obtain baseClass functionality, what good is MyClass then?
Let us not forget that what we were talking about was calling base functionality from the baseClass and you cannot use MyBase in the baseClass. More, MyClass is about enforcing and assuring the consumer that when he calls an inherited method M1 that in turn calls (using MyClass) another inherited method M2 that was in the meantime overridden, the base class code will execute always for M2. MyClass never invokes base class functionality but is merely used in the base class to set an execution path in stone avoiding the situation when polymorphism would redirect the execution to the new version of M2 thus changing M1’s expected functionality.