Why do I get the error "Object reference not set to an instance of an object"?

Published 06 May 04 09:01 PM

The code is trying to access a member of a reference type variable that is set to null.

Given the following class, let's examine some code that could be in the Main method:

using System;

class Foo
{
 static void Main()
 {
  // foo has not been instantiated
  Foo foo = null;

  // implementation to be discussed...
 }

 public int BarProperty
 {
  get { return 0; }
 }

 public string BarMethod() 
 {
  return null;
 }
}

Looking at Main, notice that foo is set to null.  Your situation will not be this explicit because the variable you are trying to use could be a class field, parameter, or local variable that was once instantiated but was subseqently set to null.  Given that foo is null, the following code will throw a NullReferenceException:

  try
  {
   // foo is null, and you can't call
   // BarProperty on null.
   int resultBad = foo.BarProperty;
  }
  catch (NullReferenceException nre)
  {
   Console.WriteLine(
    "\nCan't read BarProperty, foo is null.\n" + 
    nre.Message);
  }

Since foo is null, you can not use its members.  This was a property, but the following code demonstrates calling a method:

  try
  {
   // foo is null, and you can't call
   // BarMethod on null.
   foo.BarMethod();
  }
  catch (NullReferenceException nre)
  {
   Console.WriteLine(
    "\nCan't call BarMethod(), foo is null.\n" + 
    nre.Message);
  }

The code above throws a NullReferenceException because foo is still null.  It doesn't matter that the first call was a property and the second is a method - they are both members of the type.

Now, to fix this problem, you must ensure that foo is instantiated before it is used.  The following code instantiates foo and the previous problems are solved:

  // now we have an instance
  foo = new Foo();

  // works fine
  int resultGood = foo.BarProperty;

Since foo now refers to a valid instance, the code can call any of its members.  This was easier than many null reference problems.  Sometimes you have multiple levels of indirection, leaving you with a scenario you didn't expect.  Assuming that foo now references an object, there is still a problem with the following code:

  try
  {
   // still breaks because BarMethod() returned
   // null and you can't call Trim() on null.
   foo.BarMethod().Trim();
  }
  catch (NullReferenceException nre)
  {
   Console.WriteLine(
    "\nCan't call Trim(), BarMethod() returns null.\n" + 
    nre.Message);
  }

The problem occurs in the code above because BarMethod returned null, which means that the code is trying to call the Trim method on a string reference that is set to null

The proper way to fix this problem is to debug BarMethod to find out why it returned null.  That assumes BarMethod is not supposed to return null.  If, in your application, it made sense for BarMethod to sometimes return null, then you would have to check the return value of BarMethod before you called any members of the return value.

[Author: Joe Mayo]

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# brady gaster said on May 7, 2004 9:16 AM:
I really hate to ask this question, but do people really ask THAT question (for code written like this?) Call me a nay-sayer, but this seems a little, well.. obvious, now doesn't it?
# Joe Mayo [C# MVP] said on May 7, 2004 12:07 PM:
The question and the problem comes in many different forms. To me, picking just one scenario may not be descriptive of the cause of the problem. So, I approached it in a generic way. The subject contains text from the message that appears when a NullReferenceException is thrown, which I felt would be identifiable for someone looking for and answer to this problem in the FAQ. Google gives me over 5,000 entries on "NullReferenceException". The description explains why this type of problem happens. It is designed for the reader to be able to draw a parallel between the explanation and their own problem. While the message and description is obvious to the majority of C# developers, it is not to many beginners who have only a vague idea of what an object or reference is in the first place. I certainly respect your point-of-view and understand that some people prefer to see content targeted at their level of understanding. Do you think this should have the title modified, content modified, or removed?
# Chris Nahr said on May 8, 2004 1:52 AM:
Brady, just take a look at the microsoft.public.dotnet newsgroups... it sounds incredible but I swear we get at least one such post per week! "Null reference exception... help, what's happening, what's that, what am I doing wrong!?"

People who are new to managed code apparently simply don't understand this message, and since it's generated by .NET they assume there must be a problem with .NET (and not with their program).

So I think this log entry and its title are appropriate, I only worry that the target audience that doesn't know about object references won't know about this blog either... but at least we can post a link on the MS newsgroups now. :-)
# Joku said on May 13, 2004 7:22 PM:
Though it's been a while, I can still remember pondering that error. When you mainly have done languages which do not have even simple objects, the meaning of object instances will take a while to grasp.

It could be good idea to have a easily noticeable and clickable link in the error message which points to a help file with an explanation that has been proven to be understandable to a person who never heard of objects, and that help file would also carry link to some OO-basics place.
# Lance said on May 27, 2004 7:17 AM:
Good post! I will definitely point people to it the next 1000 times I get asked such a question! :)

On a side-note, I worry that new developers looking at the code will merely latch-on to the way your Try/Catch is written and add an exception-filter for NullReferenceException. This is a prime candidate for using exceptions and try/catch as flow-control, which is explicitly prohibited by almost every coding standard.

You might consider just commenting where the exception would occur, rather than including that exception filter.

Thanks
# Alex said on July 7, 2004 12:55 AM:
Hello !

Let me post you a 1001st "Object reference not set to an instance of an object" question :)

I' ve got such a code:

-----------------SimpleCMD.cs

using System;
using System.EnterpriseServices;
using System.Runtime.InteropServices;

namespace CMDServer
{
public interface ISimpleCMD
{
int MyFunction();
}

[ClassInterface(ClassInterfaceType.AutoDual)]
public class SimpleCMD: ServicedComponent,ISimpleCMD
{
public SimpleCMD() {}
public int MyFunction()
{
return 5;
}
}
}

------------------AssemblyInfo.cs

using System.Reflection;
using System.Runtime.CompilerServices;
using System.EnterpriseServices;

[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: AssemblyVersion("1.0.*")]

[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("keyfile.snk")]
[assembly: AssemblyKeyName("")]

[assembly: ApplicationName( "C# CMD Compiled Server" )]
[assembly: ApplicationActivation( ActivationOption.Server )]
[assembly: ApplicationAccessControl(false ) ]
----------------------------------------------

The client code in VB looks like

Dim App As New SimpleCMD
MsgBox App.MyFunction

The problem:

When I build in Visual Studio, everything works fine.

If I build from command line:

sn -k keyfile.snk

csc /r:System.EnterpriseServices.dll /t:library /out:CMDSimpleServer.dll SimpleCMD.cs AssemblyInfo.cs

gacutil /i CMDSimpleServer.dll

regsvcs CMDSimpleServer.dll

I get message "Object reference not set to an instance of an object."

What am I doing wrong?
Thank you.





# NM said on July 15, 2004 2:57 AM:
I'm having the same problem. I'm using an accessor, I've instantiated the variable, but i still the get the null reference.
# DaveF said on July 21, 2004 2:05 PM:
I've been programming in OO languages for many years now. But I'm new to C# and trying to call functions from a DLL. I'm getting this message and can't figure out why. Here's the code:

using System;
using System.Runtime.InteropServices;

namespace PiApi {

public class clsPiApi {

[DllImportAttribute("piapi32.dll", EntryPoint="pipt_findpoint", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall )]
public static extern int findpoint([MarshalAsAttribute(UnmanagedType.LPStr)] string TagName ,
[MarshalAsAttribute(UnmanagedType.I4)] int pt);

public int getPoint(string TagName) {
int ptno = new int();
int retVal = new int();

try {
retVal = findpoint(TagName, ptno);
} catch(System.NullReferenceException e) {
System.Console.Write("Error " + e.Message + "\n\n");
}

if(retVal == 0){
return ptno;
} else {
return 0;
}
} // end of getPoint

} // end of class
} // end of namespace


namespace Test {
using PiApi;

public class MyTest {
public static int Main(){
clsPiApi objPI = new clsPiApi();

System.Console.Write("Tag for pipt FIC3499.MD is {0}.\n", objPI.getPoint("FIC3499.MD"));
return 0;
}
}
}

Any ideas?
# Venugopal said on August 6, 2004 8:26 AM:
I am having the same problem too.
My Code looks like this:
Public Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim strIndexname As String, strPriceType As String, strDateType As String
Dim strMonth As String, strStartdt As String, strEnddt As String, strConn As String
Dim objShell As New MPIndex.clsMPBShell
Dim cnn As New ADODB.Connection
Dim intLocation As Short, i As Integer
Dim objColIndex As MPIndex.colIndex = New MPIndex.colIndex
Dim objIndex As New MPIndex.clsIndex
Dim PriceKeyID As Integer
Dim lngStart As Long, lngEnd As Long
Dim mvarArrPrice(,)
Dim Duration As New MPIndex.TimeDuration
Dim lngCalendarID As Long, lngCount As Long
Dim StartDate As Date, EndDate As Date, TradeDate As Date
Dim RetrieveMethod As MPIndex.DataRetrieveMethod
Dim blnIncludeVolume As Boolean, blnExcludeWeekends As Boolean
strIndexname = Request.Form("lstIndexname")
strPriceType = Request.Form("PriceType")
strDateType = Request.Form("DateType")
strMonth = Request.Form("month1")
strStartdt = Request.Form("startdt")
strEnddt = Request.Form("enddt")
txt.Text = strIndexname
strConn = "Provider=SQLOLEDB;DRIVER={SQL Server};Server=WPODB001;Database=NYPAProd;Trusted_Connection=Yes"
cnn.ConnectionString = strConn
cnn.ConnectionTimeout = 20
cnn.Open()
'objShell = New MPIndex.clsMPBShell
With objShell
.Connection = cnn
.ConnectToDatabase()
End With
'objColIndex = New MPIndex.colIndex
PriceKeyID = 2067
objColIndex = objShell.RefColIndex
strIndexname = "NYISO DAM LBMP - Generator (Brentwood)"
intLocation = objColIndex.Find(PriceKeyID)
txt.Text = intLocation
objIndex = objColIndex.Item(intLocation)
Duration = MPIndex.TimeDuration.icHour
lngCalendarID = objIndex.CalendarID

End Sub

I am using a COM Component called MPIndex.clsMPBShell and I get the Object Reference not set error. Actually, according to the DLL documentation, the Find method in the secondlast line should return 26 as the value passed to the Find method is hardcoded. But it returns 0 and due to this, the objIndex is not being set. Can anybody tell me where I am going wrong? I have the DLL registered and added the reference to my project.

Thanks,
Venu
# Jack said on October 20, 2009 2:30 AM:

I always meet this exception:)

# ananth said on December 4, 2009 4:52 AM:

using System.Collections;

using System.Configuration;

using System.Data;

using System.Linq;

using System.Web;

using System.Web .Configuration ;

using System.Data .SqlClient ;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

using System.Collections.Generic;

public partial class Default2 : System.Web.UI.Page

{

   public string connection = WebConfigurationManager.AppSettings["pubs1"].ToString();

   SqlConnection cnew = new SqlConnection(ConfigurationManager.AppSettings["pubs1"].ToString());// new SqlConnection();

   SqlCommand cmd = new SqlCommand();

   protected void Page_Load(object sender, EventArgs e)

   {

       if (!IsPostBack)

       {

          bindgrid();

       }

   }

   void bindgrid()

   {

       List <company> item=new List <company>(5);

       for(int i=0;i<5;i++)

       {

           company c=new company ();

           item.Add (c);

       }

       GridView1.DataSource = item;

       GridView1.DataBind();

   }

   protected void clearButton_Click(object sender, EventArgs e)

   {

       bindgrid();

   }

   void beginadd()

   {

     //SqlConnection cnew = new SqlConnection(connection);

     //SqlCommand cmd = new SqlCommand();

       cnew.Open();

       SqlTransaction tran = cnew.BeginTransaction();

       cmd.Connection = cnew;

       cmd.Transaction = tran;

       cmd.CommandText = "insert into msm_company(comp_id,comp_name)values (@companyid,@companyName";

       SqlParameter p1 = new SqlParameter("@companyid", SqlDbType.VarChar);

       SqlParameter p2 = new SqlParameter("@companyName", SqlDbType.VarChar);

       cmd.Parameters.Add(p1);

       cmd.Parameters.Add(p2);

       //cnew.Close();

   }

   void addcustomer(string companyid,string companyname)

       {

           try

           {

               //cnew.Open();

               cmd.Parameters[0].Value = companyid;

               cmd.Parameters[1].Value = companyname;

               cmd.ExecuteNonQuery();

           }

       catch

           {

           cmd.Transaction .Rollback ();

       }

   }

   void completeadd()

   {

       try

       {

           //cmd.Transaction.Commit();

           Label1.Text = "record added successfully";

       }

       catch (Exception ex)

       {

           Label1.Text = "error inserting record";

           Label1.Text += ex.Message;

       }

       finally

       {

           cnew.Close();

       }

   }

   protected void saveButton_Click(object sender, EventArgs e)

   {

       beginadd();

       foreach (GridViewRow row in GridView1.Rows)

       {

           if (row.RowType == DataControlRowType.DataRow)

           {

               string companyid = ((TextBox)row.FindControl("textbox1")).Text;

               string companyname = ((TextBox)row.FindControl("textbox2")).Text;

               if (companyid != "")

               {

                   addcustomer(companyid, companyname);

               }

           }

       }

       completeadd();

   }

}

this is my code.Why do I get the error "Object reference not set to an instance of an object"?

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

This Blog

Syndication

Page view tracker