January 2004 - Posts
Me
Me is what really symbolizes VB.NET isn't it? Where is it really applicable ? Lets see:
- To pass the current executing instance to some other Class or Structure method as a parameter. For example, consider this Print method.
Sub Print()
Console.WriteLine(Me)
End Sub
- I have seen samples where Me is prefixed for every member access. I dont think that is really necessary. But sometimes, this can be used differentiate between a method parameter and an instance member. For example:
Public Sub SetValue(ByVal Value as Int16)
Me.Value = Value
End Sub
I would choose to prefix all instance members with an _, especially, if they are private. Like “_value“.
MyBase
MyBase is a keyword used to call the methods of immediate base class from a method in a derived class. Typically, this would be called in overloaded Constructors and the Finalizer. For example:
Sub New(Byval i as Int16)
MyBase.New(i)
'Do specific initialization
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
' Do Specific cleanup
End Sub
MyClass
We all would be comfortable with the semantics of Me and MyBase. But MyClass is somewhat tricky. The MSDN definition reads: “MyClass 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. Therefore, the method being called is not affected by overriding in a derived class“. What does this mean?
There may be situations where a base class method calls another method in the same class which may be declared as Overridable (a virtual method). So, the executing code cannot make the assumption that the current instance is of the base type. So, a method call in the base may actually be dispatched to a derived class instance (if overridden). Therefore, the logic in the calling method may fail if assumptions are made on the type of the instance.
MyClass addresses this situation by making sure that the current class's method is dispatched and not the overridden method. Have a look at this MSDN sample (which is actually pretty clear)
Class BaseClass
Public Overridable Sub MyMethod()
MsgBox("Base class string")
End Sub
Public Sub UseMe()
Me.MyMethod() ' Use calling class's version, even if an override.
End Sub
Public Sub UseMyClass()
MyClass.MyMethod() ' Use this version and not any override.
End Sub
End Class
Class DerivedClass : Inherits BaseClass
Public Overrides Sub MyMethod()
MsgBox("Derived class string")
End Sub
End Class
Class TestClasses
Sub StartHere()
Dim TestObj As DerivedClass = New DerivedClass()
TestObj.UseMe() ' Displays "Derived class string".
TestObj.UseMyClass() ' Displays "Base class string".
End Sub
End Class
There are some limitations of using these keywords and the link given below explains these:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcn7/html/vaconInheritanceBasics.asp
Another interesting thing to note is that there is no equivalent of MyClass in C#. It is debatable which compiler implementation is right or wrong. But I prefer the way it works in C# because the behavior of the code is more predictable.
What do you think is the answer to this question?
I have coded an application using .NET. To move to the 64 bit platform, I need to...
A) Recompile everything on a 64 bit compiler.
B) Won't do anything. (Stick to 32 bit and hope that WOW64 works)
C) Can’t do anything. (Document that we do not support 64 bit platform)
D) Rewrite/revamp everything referring to the Intel IA-64 reference manual.
E) I don’t need to do anything. My code would take the full advantage of a 64 bit platform.
One of the primary purpose of .NET - abstracting the underlying platform (processor architecture) from the applications that target the CLR. The CLR does all the hard work for you. Just sit back and enjoy the managed execution ride. In the the words of Don Box : “The CLR is Omnipotent and Omnipresent“. So,
A) Recompile everything on a 64 bit compiler.
Not required for managed apps. You however have to do that for your x86 applications if you need to take the advantage of 64 bit addressing.
B) Won't do anything. (Stick to 32 bit and hope that WOW64 works)
32 bit apps can run on a 64 bit windows without a recompile. But these run on a layer called WOW64 (Windows on Windows). This layer is similar to NTVDM in Windows 2000 used to run old 16 bit applications.
You will be surprised to know that VS.NET will continue to be a 32 bit application and hence be running on WOW64.
C) Can’t do anything. (Document that we do not support 64 bit platform)
Refer to D)
D) Rewrite/revamp everything referring to the Intel IA-64 reference manual.
Ha Ha..))
E) I don’t need to do anything. My code would take the full advantage of a 64 bit platform.
There are only certain circumstances where your managed code might behave differently and you might need to do some additional work. These are:
- Complex Floating point operations like Sin(1.e37) .
- Working with unmanaged pointers in managed code or interopping
Have a look at this MSDN TV presentation on this same topic to get a better idea (This is where I got Sin(1.e37)).
http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20030731CLRCB/manifest.xml
BTW, "Whidbey" comes bundled with a 64 bit runtime.
Site of the Week - TheServerSide.NET
A Cool site. Lots of resources on .NET including news, reviews and Tech talks. The login still doesn't seem to work though
Articles for the week
1. Win32 -> .NET API mapping list at MSDN
An exhaustive table depicting Win32 API and their corresponding classes and methods in .NET
2. An Extensive Examination of Data Structures
This is part 2 of the six part series on Data structures in .NET. A good read
Here's a short story with an "Optional" twist and a surprising moral.
Flashback
VB6 supports optional parameters. The VB6 compiler is happy to see these parameters without the default value. We all know. In VB6, we could also check whether an optional parameter was passed by the caller or not of using the IsMissing method. But this method worked only on Variants. Why? Because, the other types of variables where automatically initialized to their default values. So, there is no way of checking whether the value passed is the default value or actual value.
Present day
Variants are disbanded from VB.NET. So, its buddy, the IsMissing method was also pushed out. Our short story does not end here. Here's the twist. VB.NET also supports optional parameters. We all know. VB.NET however does not support optional parameters without default values. We all know this too. What we may not know is C# (and possibly other languages that target the CLR) does not allow optional arguments. So, how does one program written with C# consume a method written in VB.NET declared with default parameters.
The answer is - That patient programmer must pass System.Reflection.Missing.Value to force the default value to be taken. Ofcource, this has to be done for all optional arguments in the method call and hence, can be really frustrating for a C# dev.
Moral of the storty
It is always better to use overloading than to use optional arguments. So, VB6 devs, please come out of your "Optional" habit. If you are addicted to Optional and are ticklish about overloading, then try limiting that addiction to Internal classes only ( Ahem…I mean Friends!)
Can you tell me what is the easiest way (minimal coding effort) to share data (memory) between two applications/processes on the same machine ? Lemme give you a couple of hints.
It is not:
1) Remoting
2) Pipes
3) MMF (Memory Mapped Files)
4) DCOM
And the final hint, we cannot survive in this industry without it (literally).
You guessed it right!
The cornerstone of an average developer's high productivity at work (CTRL-C, CTRL-V!) - The Clip Board.
The Windows clip board is accessible through System.Windows.Forms.Clipboard class. We can use the SetDataObject shared method to add objects to the clipboard (lets call it CB). Likewise, we can use GetDataObject to retrieve contents from the CB. We can also serialize complex objects like the DataSet and store it in the CB for consumption.
Though this approach is simple, it is definitely not elegant, as the clipboard is something that all applications can access. Hence, we cannot ensure a a reliable sharing (for instance, using Outlook, I can purge the CB). For reliable sharing of information, we can use one of the methods metioned in the beginning of the post.
Here's a sample code snippet using the ClipBoard:
If Environment.CommandLine.IndexOf("-Put") > 0 Then
System.Windows.Forms.Clipboard.SetDataObject("Hello from here", True)
Else
Dim iData As System.Windows.Forms.IDataObject = Clipboard.GetDataObject()
If iData.GetDataPresent(DataFormats.StringFormat) Then
Console.WriteLine(iData.GetData(DataFormats.StringFormat))
Else
Console.WriteLine("Could not retrieve data off the clipboard.")
End If
End If
It is noteworthy (obvious actually) that the clipboard is extensively used in windows applications in the implementations of Drag - Drop, Cut /Copy - Paste etc.
Well, I am talking about the "Friend" access specifier of VB.NET here.
Honestly, I am not comfortable with keyword Friend and its actual semantics in VB. A Friend member is something that can be seen only within an assembly. That's it - it does not promise any more. In C++, a friend is something that can peep into your object's private members.
I think that is the reason why it is called by a more intuitive "internal" in C#. I agree, this was the way Friends worked in VB6 and hence the same semantics.
Okay now, to a lesser know (& interesting) fact about Friends. Try this:
1. Create a class and have Friend as its access qualifier.
2. Derive a class from the above and have Public as its access qualifier.
Our humble compiler would disallow the same. Can you explain why our man was unhappy here ? Quite logical. If the above case were to be allowed, then public derived class would serve as windows to the hidden internal types. This would be a sort of access violation and hence this behavior makes sense.
Signing off with "Friendly" regards...
Vinod hinted me about this yesterday and this is indeed very interesting. A concept called String Interning in CLR. Consider the following snippet:
Dim str1 as String = "Manoj"
Dim str2 as String = "Manoj"
What would you get if you did Object.ReferenceEquals (str1,str2)? Till yesterday, I thought this would be false. Actually, It would be true!
This is because the CLR maintains an internal pool of strings and stores literals in it (like "Manoj"). So, to conserve memory, the CLR would set str1 and str2 to point to the same location on the heap.
Note that the CLR would automatically add only literals to the pool. Results of string operations like concatenation would not be added to the pool. To add these to the pool explicitly, you need to use the Intern shared method of the String class. You can use IsInterned to checked whether a sting has an Interned reference.
You may ask. Whay can't every type have an internal pool similarly? The answer to this lies in the fact that only String objects are immutable.
Try these:
1. Create an Interface with a method
2. Create a class that implements this interface
3. Create a class that derives from the class above and also implements the interface.
Does your compiler allow this?
VB.NET does not allow you to do this. C#however, is comfortable with this. This because C# allows separate implementations for Interface methods. Something like:
public class Derived: Base, IMyItf
{
public int Func(int i,int j)
{
return 100;
}
int IMyItf.Func(int i,int j)
{
return 1000;
}
}
There is no such facility in VB.NET :(
Secondly, try this:
1. Create an interface with a method
2. Create a class and implement the interface
3. Create a class derived from the class above, have a method with the same signature as the one in base class
Now, which method is called if I use an Interface reference to call upon the method ? Can you explain??
Interestingly, the one in the base class is called irrespectively of whether you qualify your derived class method with Shadows or not. This is because, VB.NET requires you to explicitly mention that you are implementing the interface method(which is not mandatory in C#), Something like:
Public Function Add(ByVal a As Short, ByVal b As Short) As Object Implements IMyItf.Add
Return 100
End Function
In our example, only the base class has such an implementation. So, the method of the base is the one called. With C# too, the behavior is the same.
A Final twist, make the method in the base class private and repeat the steps. See what happens!
VB.NET will be glad to call upon the base class method though it is private. Remember, access specifiers are of no consequence here for calling methods through interface references.
With C# it is a slightly different story. C# will throw a compiler error complaining that the method (in the base) needs to public. However, if you have a separate interface method (like the example in Q1), that method will be called. Note that the method will not need an access specifier. In fact C# doesn’t allow you to add one either!
A great writeup by one of my favorite writers - Jeff Richter.
http://www.codeguru.com/net_general/Insights_NGen.html
Interesting thing to note here is that last caveat mentioned about NGEN: Ignored NGen'd File in Some Domain Load Scenarios.