I have some code and when it executes, it throws a NullReferenceException
, saying:
Object reference not set to an instance of an object.
What does this mean, and what can I do to fix this error?
I have some code and when it executes, it throws a NullReferenceException
, saying:
Object reference not set to an instance of an object.
What does this mean, and what can I do to fix this error?
Simon Mourier gave this example:
where an unboxing conversion (cast) from
object
(or from one of the classesSystem.ValueType
orSystem.Enum
, or from an interface type) to a value type (other thanNullable<>
) in itself gives theNullReferenceException
.In the other direction, a boxing conversion from a
Nullable<>
which hasHasValue
equal tofalse
to a reference type, can give anull
reference which can then later lead to aNullReferenceException
. The classic example is:Sometimes the boxing happens in another way. For example with this non-generic extension method:
the following code will be problematic:
These cases arise because of the special rules the runtime uses when boxing
Nullable<>
instances.Interestingly, none of the answers on this page mention the two edge cases, hope no one minds if I add them:
Edge case #1: concurrent access to a Dictionary
Generic dictionaries in .NET are not thread-safe and they sometimes might throw a
NullReference
or even (more frequent) aKeyNotFoundException
when you try to access a key from two concurrent threads. The exception is quite misleading in this case.Edge case #2: unsafe code
If a
NullReferenceException
is thrown byunsafe
code, you might look at your pointer variables, and check them forIntPtr.Zero
or something. Which is the same thing ("null pointer exception"), but in unsafe code, variables are often cast to value-types/arrays, etc., and you bang your head against the wall, wondering how a value-type can throw this exception.(Another reason for non-using unsafe code unless you need it, by the way)
It means that the variable in question is pointed at nothing. I could generate this like so:
That will throw the error because while I've declared the variable "
connection
", it's not pointed to anything. When I try to call the member "Open
", there's no reference for it to resolve, and it will throw the error.To avoid this error:
object == null
.JetBrains' Resharper tool will identify every place in your code that has the possibility of a null reference error, allowing you to put in a null check. This error is the number one source of bugs, IMHO.
Another general case where one might receive this exception involves mocking classes during unit testing. Regardless of the mocking framework being used, you must ensure that all appropriate levels of the class hierarchy are properly mocked. In particular, all properties of
HttpContext
which are referenced by the code under test must be mocked.See "NullReferenceException thrown when testing custom AuthorizationAttribute" for a somewhat verbose example.
NullReference Exception — Visual Basic
The
NullReference Exception
for Visual Basic is no different from the one in C#. After all, they are both reporting the same exception defined in the .NET Framework which they both use. Causes unique to Visual Basic are rare (perhaps only one).This answer will use Visual Basic terms, syntax, and context. The examples used come from a large number of past Stack Overflow questions. This is to maximize relevance by using the kinds of situations often seen in posts. A bit more explanation is also provided for those who might need it. An example similar to yours is very likely listed here.
Note:
NullReferenceException
(NRE), how to find it, how to fix it, and how to avoid it. An NRE can be caused many ways so this is unlikely to be your sole encounter.Basic Meaning
The message "Object not set to an instance of Object" means you are trying to use an object which has not been initialized. This boils down to one of these:
Finding The Cause
Since the problem is an object reference which is
Nothing
, the answer is to examine them to find out which one. Then determine why it is not initialized. Hold the mouse over the various variables and Visual Studio (VS) will show their values - the culprit will beNothing
.You should also remove any Try/Catch blocks from the relevant code, especially ones where there is nothing in the Catch block. This will cause your code to crash when it tries to use an object which is
Nothing
. This is what you want because it will identify the exact location of the problem, and allow you to identify the object causing it.A
MsgBox
in the Catch which displaysError while...
will be of little help. This method also leads to very bad Stack Overflow questions, because you can't describe the actual exception, the object involved or even the line of code where it happens.You can also use the
Locals Window
(Debug -> Windows -> Locals) to examine your objects.Once you know what and where the problem is, it is usually fairly easy to fix and faster than posting a new question.
See also:
Examples and Remedies
Class Objects / Creating an Instance
The problem is that
Dim
does not create a CashRegister object; it only declares a variable namedreg
of that Type. Declaring an object variable and creating an instance are two different things.Remedy
The
New
operator can often be used to create the instance when you declare it:When it is only appropriate to create the instance later:
Note: Do not use
Dim
again in a procedure, including the constructor (Sub New
):This will create a local variable,
reg
, which exists only in that context (sub). Thereg
variable with module levelScope
which you will use everywhere else remainsNothing
.To be clear,
Dim
(orPrivate
) only declares a variable and itsType
. The Scope of the variable - whether it exists for the entire module/class or is local to a procedure - is determined by where it is declared.Private | Friend | Public
defines the access level, not Scope.For more information, see:
Arrays
Arrays must also be instantiated:
This array has only been declared, not created. There are several ways to initialize an array:
Note: Beginning with VS 2010, when initializing a local array using a literal and
Option Infer
, theAs <Type>
andNew
elements are optional:The data Type and array size are inferred from the data being assigned. Class/Module level declarations still require
As <Type>
withOption Strict
:Example: Array of class objects
The array has been created, but the
Foo
objects in it have not.Remedy
Using a
List(Of T)
will make it quite difficult to have an element without a valid object:For more information, see:
Lists and Collections
.NET collections (of which there are many varieties - Lists, Dictionary, etc.) must also be instantiated or created.
You get the same exception for the same reason -
myList
was only declared, but no instance created. The remedy is the same:A common oversight is a class which uses a collection
Type
:Either procedure will result in an NRE, because
barList
is only declared, not instantiated. Creating an instance ofFoo
will not also create an instance of the internalbarList
. It may have been the intent to do this in the constructor:As before, this is incorrect:
For more information, see
List(Of T)
Class.Data Provider Objects
Working with databases presents many opportunities for a NullReference because there can be many objects (
Command
,Connection
,Transaction
,Dataset
,DataTable
,DataRows
....) in use at once. Note: It does not matter which data provider you are using -- MySQL, SQL Server, OleDB, etc. -- the concepts are the same.Example 1
As before, the
ds
Dataset object was declared, but an instance was never created. TheDataAdapter
will fill an existingDataSet
, not create one. In this case, sinceds
is a local variable, the IDE warns you that this might happen:When declared as a module/class level variable, as appears to be the case with
con
, the compiler can't know if the object was created by an upstream procedure. Do not ignore warnings.Remedy
Example 2
A typo is a problem here:
Employees
vsEmployee
. There was noDataTable
named "Employee" created, so aNullReferenceException
results trying to access it. Another potential problem is assuming there will beItems
which may not be so when the SQL includes a WHERE clause.Remedy
Since this uses one table, using
Tables(0)
will avoid spelling errors. ExaminingRows.Count
can also help:Fill
is a function returning the number ofRows
affected which can also be tested:Example 3
The
DataAdapter
will provideTableNames
as shown in the previous example, but it does not parse names from the SQL or database table. As a result,ds.Tables("TICKET_RESERVATION")
references a non-existent table.The Remedy is the same, reference the table by index:
See also DataTable Class.
Object Paths / Nested
The code is only testing
Items
while bothmyFoo
andBar
may also be Nothing. The remedy is to test the entire chain or path of objects one at a time:AndAlso
is important. Subsequent tests will not be performed once the firstFalse
condition is encountered. This allows the code to safely 'drill' into the object(s) one 'level' at a time, evaluatingmyFoo.Bar
only after (and if)myFoo
is determined to be valid. Object chains or paths can get quite long when coding complex objects:It is not possible to reference anything 'downstream' of a
null
object. This also applies to controls:Here,
myWebBrowser
orDocument
could be Nothing or theformfld1
element may not exist.UI Controls
Among other things, this code does not anticipate that the user may not have selected something in one or more UI controls.
ListBox1.SelectedItem
may well beNothing
, soListBox1.SelectedItem.ToString
will result in an NRE.Remedy
Validate data before using it (also use
Option Strict
and SQL parameters):Alternatively, you can use
(ComboBox5.SelectedItem IsNot Nothing) AndAlso...
Visual Basic Forms
This is a fairly common way to get an NRE. In C#, depending on how it is coded, the IDE will report that
Controls
does not exist in the current context, or "cannot reference non-static member". So, to some extent, this is a VB-only situation. It is also complex because it can result in a failure cascade.The arrays and collections cannot be initialized this way. This initialization code will run before the constructor creates the
Form
or theControls
. As a result:somevar
assignment will result in an immediate NRE because Nothing doesn't have a.Text
propertyReferencing array elements later will result in an NRE. If you do this in
Form_Load
, due to an odd bug, the IDE may not report the exception when it happens. The exception will pop up later when your code tries to use the array. This "silent exception" is detailed in this post. For our purposes, the key is that when something catastrophic happens while creating a form (Sub New
orForm Load
event), exceptions may go unreported, the code exits the procedure and just displays the form.Since no other code in your
Sub New
orForm Load
event will run after the NRE, a great many other things can be left uninitialized.Note this applies to any and all control and component references making these illegal where they are:
Partial Remedy
It is curious that VB does not provide a warning, but the remedy is to declare the containers at the form level, but initialize them in form load event handler when the controls do exist. This can be done in
Sub New
as long as your code is after theInitializeComponent
call:The array code may not be out of the woods yet. Any controls which are in a container control (like a
GroupBox
orPanel
) will not be found inMe.Controls
; they will be in the Controls collection of that Panel or GroupBox. Nor will a control be returned when the control name is misspelled ("TeStBox2"
). In such cases,Nothing
will again be stored in those array elements and an NRE will result when you attempt to reference it.These should be easy to find now that you know what you are looking for:![VS shows you the error of your ways](https://i.stack.imgur.com/5ndSA.jpg)
"Button2" resides on a
Panel
Remedy
Rather than indirect references by name using the form's
Controls
collection, use the control reference:Function Returning Nothing
This is a case where the IDE will warn you that 'not all paths return a value and a
NullReferenceException
may result'. You can suppress the warning, by replacingExit Function
withReturn Nothing
, but that does not solve the problem. Anything which tries to use the return whensomeCondition = False
will result in an NRE:Remedy
Replace
Exit Function
in the function withReturn bList
. Returning an emptyList
is not the same as returningNothing
. If there is a chance that a returned object can beNothing
, test before using it:Poorly Implemented Try/Catch
A badly implemented Try/Catch can hide where the problem is and result in new ones:
This is a case of an object not being created as expected, but also demonstrates the counter usefulness of an empty
Catch
.There is an extra comma in the SQL (after 'mailaddress') which results in an exception at
.ExecuteReader
. After theCatch
does nothing,Finally
tries to perform clean up, but since you cannotClose
a nullDataReader
object, a brand newNullReferenceException
results.An empty
Catch
block is the devil's playground. This OP was baffled why he was getting an NRE in theFinally
block. In other situations, an emptyCatch
may result in something else much further downstream going haywire and cause you to spend time looking at the wrong things in the wrong place for the problem. (The "silent exception" described above provides the same entertainment value.)Remedy
Don't use empty Try/Catch blocks - let the code crash so you can a) identify the cause b) identify the location and c) apply a proper remedy. Try/Catch blocks are not intended to hide exceptions from the person uniquely qualified to fix them - the developer.
DBNull is not the same as Nothing
The
IsDBNull
function is used to test if a value equalsSystem.DBNull
: From MSDN:Remedy
As before, you can test for Nothing, then for a specific value:
Example 2
FirstOrDefault
returns the first item or the default value, which isNothing
for reference types and neverDBNull
:Controls
If a
CheckBox
withchkName
can't be found (or exists in aGroupBox
), thenchk
will be Nothing and be attempting to reference any property will result in an exception.Remedy
The DataGridView
The DGV has a few quirks seen periodically:
If
dgvBooks
hasAutoGenerateColumns = True
, it will create the columns, but it does not name them, so the above code fails when it references them by name.Remedy
Name the columns manually, or reference by index:
Example 2 — Beware of the NewRow
When your
DataGridView
hasAllowUserToAddRows
asTrue
(the default), theCells
in the blank/new row at the bottom will all containNothing
. Most attempts to use the contents (for example,ToString
) will result in an NRE.Remedy
Use a
For/Each
loop and test theIsNewRow
property to determine if it is that last row. This works whetherAllowUserToAddRows
is true or not:If you do use a
For n
loop, modify the row count or useExit For
whenIsNewRow
is true.My.Settings (StringCollection)
Under certain circumstances, trying to use an item from
My.Settings
which is aStringCollection
can result in a NullReference the first time you use it. The solution is the same, but not as obvious. Consider:Since VB is managing Settings for you, it is reasonable to expect it to initialize the collection. It will, but only if you have previously added an initial entry to the collection (in the Settings editor). Since the collection is (apparently) initialized when an item is added, it remains
Nothing
when there are no items in the Settings editor to add.Remedy
Initialize the settings collection in the form's
Load
event handler, if/when needed:Typically, the
Settings
collection will only need to be initialized the first time the application runs. An alternate remedy is to add an initial value to your collection in Project -> Settings | FooBars, save the project, then remove the fake value.Key Points
You probably forgot the
New
operator.or
Something you assumed would perform flawlessly to return an initialized object to your code, did not.
Don't ignore compiler warnings (ever) and use
Option Strict On
(always).MSDN NullReference Exception
The error line "Object reference not set to an instance of an object. " states that you have not assigned instance object to a object reference and still you are accessing properies/methods of that object.
for example: let say you have a class called myClass and it contains one property prop1.
Now you are accessing this prop1 in some other class just like below:
above line throws error because reference of class myClass is declared but not instantiated or an instance of object is not assigned to referecne of that class.
To fix this you have to instantiate (assign object to reference of that class).