Tuesday, December 17, 2013

Object is Nothing but can access the members without NullReferenceException in VB.Net

All the .Net developers will be familiar with NullReferenceExpception. At least once this exception should have hit in our code. When we try to access a member of any object variable which is null or Nothing(in VB.Net) at that time, it will throw NullReferenceException. In almost all scenarios when we get such an exception its little difficult to identify which object is null. If its in VisualStudio we mouse over on all the object variables in the method and look for its value.

In our project there is one place where people occasionally sees one object shows Nothing in the watch window but the method call works. Since it is written in the initial days of project around 8 years back and written by a group of people who strived for generic implementations with strict SOLID principles, its kind of Bermuda triangle for the new generation programmers. Since it is written properly using Open-Close principle, normally there was no situations which demanded to edit that class. Whenever somebody encounters this situation during debugging, they will share experience each other. People treated it as kind of fairy place. For them it worked almost all the time. Nobody spend time to uncover the mystery of it or the people who tried were not good discoverers. See the below to see this in Visual Studio.

I met with the situation yesterday. Unfortunately in my case the object was really nothing and it started showing the NullReferenceException. When I checked with the people they were telling as that is the behaviour. They all sees it as Nothing when they mouse hover or put in the watch window. But it worked for them. After some more debugging I could see that the object is being loaded from a file and that file is not present in my machine. I copied that file and out of curiosity I debugged again. Yes I too reached the same page of others. In watch the object shows Nothing, but I can call the methods inside that.

After an hour of struggle one of my attempt put some light into it. I tried to get the type by invoking the ToString() method. It returned correct type name. That clicked it.

When we put an object into watch window or mouse over, its actually showing the ToString() value of that object. 

I could easily figure out that one of the base classes is overriding the ToString method without method body. Since its in VB.Net without option strict on, it returns nothing and that is the nothing which is shown in watch window and other debuggers.

Public Class Employee
    Private _name As String
    Public Property Name() As String
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property
    Private _Id As Integer
    Public Property Id() As Integer
            Return _Id
        End Get
        Set(ByVal value As Integer)
            _Id = value
        End Set
    End Property
    Public Overrides Function ToString() As String
 'This will not compile in C# or option strict is on in VB.Net
    End Function

Yes the unsafe VB.Net programmers are really unsafe.

No comments: