c# - What is a NullReferenceException, and how do I fix it? -
i have code , when executes, throws nullreferenceexception, saying:
object reference not set instance of object.
what mean, , can fix error?
what cause?
bottom line
you trying use null (or nothing in vb.net). means either set null, or never set @ all. 
like else, null gets passed around. if null in method "a", method "b" passed null to method "a".
the rest of article goes more detail , shows mistakes many programmers make can lead nullreferenceexception.
more specifically
the runtime throwing nullreferenceexception always means same thing: trying use reference, , reference not initialized (or once initialized, no longer initialized). 
this means reference null, , cannot access members (such methods) through null reference. simplest case:
string foo = null; foo.toupper(); this throw nullreferenceexception @ second line because can't call instance method toupper() on string reference pointing null.
debugging
how find source of nullreferenceexception? apart looking @ exception itself, thrown @ location occurs, general rules of debugging in visual studio apply: place strategic breakpoints , inspect variables, either hovering mouse on names, opening (quick)watch window or using various debugging panels locals , autos.
if want find out reference or isn't set, right-click name , select "find references". can place breakpoint @ every found location , run program debugger attached. every time debugger breaks on such breakpoint, need determine whether expect reference non-null, inspect variable , and verify points instance when expect to.
by following program flow way, can find location instance should not null, , why isn't set.
examples
some common scenarios exception can thrown:
generic
ref1.ref2.ref3.member if ref1 or ref2 or ref3 null, you'll nullreferenceexception. if want solve problem, find out 1 null rewriting expression simpler equivalent:
var r1 = ref1; var r2 = r1.ref2; var r3 = r2.ref3; r3.member specifically, in httpcontext.current.user.identity.name, httpcontext.current null, or user property null, or identity property null.
class instances
when creating variable of reference (class) type, default set null.
public class book {     public string title { get; set; } } public class example {     public void foo() {         book b1;         string title = b1.title; // never initialized b1 variable.                                     // there no book title from.     } } class type variables must either initialized or set existing class instance. initialization done using new keyword.
book b1 = new book(); indirect
public class person {     public int age { get; set; } } public class book {     public person author { get; set; } } public class example {     public void foo() {         book b1 = new book();         int authorage = b1.author.age; // never initialized author property.                                        // there no person age from.     } } if want avoid child (person) null reference, initialize in parent (book) object's constructor.
the same applies nested object initializers:
book b1 = new book { author = { age = 45 } }; while new keyword used, creates new instance of book, not new instance of person, author property still null.
array
int[] numbers = null; int n = numbers[0]; // numbers null. there no array index. array elements
person[] people = new person[5]; people[0].age = 20 // people[0] null. array allocated not                    // initialized. there no person set age for. jagged arrays
long[][] array = new long[1][]; array[0][0] = 3; // null because first dimension yet initialized.                  // use array[0] = new long[2]; first. collection/list/dictionary
dictionary<string, int> agesfornames = null; int age = agesfornames["bob"]; // agesfornames null.                                // there no dictionary perform lookup. range variable (indirect/deferred)
public class person {     public string name { get; set; } } var people = new list<person>(); people.add(null); var names = p in people select p.name; string firstname = names.first(); // exception thrown here, occurs                                   // on line above.  "p" null because                                   // first element added list null. events
public class demo {     public event eventhandler statechanged;      protected virtual void onstatechanged(eventargs e)     {                 statechanged(this, e); // exception thrown here                                 // if no event handlers have been attached                                // statechanged event     } } bad naming conventions:
if named fields differently locals, might have realized never initialized field.
public class form1 {     private customer customer;      private void form1_load(object sender, eventargs e) {         customer customer = new customer();         customer.name = "john";     }      private void button_click(object sender, eventargs e) {         messagebox.show(customer.name);     } } this can solved following convention prefix fields underscore:
private customer _customer; asp.net page life cycle:
public partial class issues_edit : system.web.ui.page {     protected testissue myissue;      protected void page_load(object sender, eventargs e)     {         if (!ispostback)         {             // called on first load, not when button clicked             myissue = new testissue();          }     }      protected void savebutton_click(object sender, eventargs e)     {         myissue.entry = "nullreferenceexception here!";     } } asp.net session values
// if "firstname" session value has not yet been set, // line throw nullreferenceexception string firstname = session["firstname"].tostring(); asp.net mvc empty view models
if exception occurs when referencing property of @model in asp.net mvc view, need understand model gets set in action method, when return view. when return empty model (or model property) controller, exception occurs when views access it:
// controller public class restaurant:controller {     public actionresult search()     {          return view();  // forgot provide model here.     } }  // razor view  @foreach (var restaurantsearch in model.restaurantsearch)  // throws. { }  <p>@model.somepropertyname</p> <!-- throws --> wpf control creation order , events
wpf controls created during call initializecomponent in order appear in visual tree.  nullreferenceexception raised in case of early-created controls event handlers, etc. , fire during initializecomponent reference late-created controls.
for example :
<grid>     <!-- combobox declared first -->     <combobox name="combobox1"                margin="10"               selectedindex="0"                selectionchanged="combobox1_selectionchanged">         <comboboxitem content="item 1" />         <comboboxitem content="item 2" />         <comboboxitem content="item 3" />     </combobox>      <!-- label declared later -->     <label name="label1"             content="label"            margin="10" /> </grid> here combobox1 created before label1. if combobox1_selectionchanged attempts reference `label1, not yet have been created.
private void combobox1_selectionchanged(object sender, selectionchangedeventargs e) {     label1.content = combobox1.selectedindex.tostring(); // nullreference here!! } changing order of declarations in xaml (i.e., listing label1 before combobox1, ignoring issues of design philosophy, @ least resolve nullreferenceexception here.
cast as
  var mything = someobject thing; this doesn't throw invalidcastexception returns null when cast fails (and when someobject null). aware of that.
linq firstordefault() , singleordefault()
the plain versions first() , single() throw exceptions when there nothing. "ordefault" versions return null in case. aware of that.
foreach
foreach throws when try iterate null collection. caused unexpected null result methods return collections.
 list<int> list = null;      foreach(var v in list) { } // exception more realistic example - select nodes xml document. throw if nodes not found initial debugging shows properties valid:
 foreach (var node in mydata.myxml.documentnode.selectnodes("//data")) ways avoid
explicitly check null , ignore null values.
  if expect reference null, can check being null before accessing instance members:
void printname(person p) {     if (p != null) {         console.writeline(p.name);     } } explicitly check null , provide default value.
  methods call expect return instance can return null, example when object being sought cannot found. can choose return default value when case:
string getcategory(book b) {     if (b == null)         return "unknown";     return b.category; } explicitly check null method calls , throw custom exception.
  you can throw custom exception, catch in calling code:
string getcategory(string booktitle) {     var book = library.findbook(booktitle);  // may return null     if (book == null)         throw new booknotfoundexception(booktitle);  // custom exception     return book.category; } use debug.assert if value should never null, catch problem earlier exception occurs.
  when know during development method maybe can, never should return null, can use debug.assert() break possible when occur:
string gettitle(int knownbookid) {     // know should never return null.     var book = library.getbook(knownbookid);        // exception occur on next line instead of @ end of method.     debug.assert(book != null, "library didn't return book known book id.");      // other code      return book.title; // never throw nullreferenceexception in debug mode. } though check will not end in release build, causing throw nullreferenceexception again when book == null @ runtime in release mode.
use getvalueordefault() nullable value types provide default value when null.
  datetime? appointment = null; console.writeline(appointment.getvalueordefault(datetime.now)); // display default value provided (datetime.now), because appointment null.  appointment = new datetime(2022, 10, 20); console.writeline(appointment.getvalueordefault(datetime.now)); // display appointment date, not default use null coalescing operator: ?? [c#] or if() [vb].
  the shorthand providing default value when null encountered:
iservice createservice(ilogger log, int32? frobpowerlevel) {     var serviceimpl = new myservice(log ?? nulllog.instance);      // note above "getvalueordefault()" can rewritten use     // coalesce operator:     serviceimpl.frobpowerlevel = frobpowerlevel ?? 5; } use null condition operator: ?. (available in c# 6 , vb.net 14):
  this called safe navigation or elvis (after shape) operator. if expression on left side of operator null, right side not evaluated, , null returned instead. means cases this:
var title = person.title.toupper(); if person not have title, throw exception because trying call toupper on property null value.
in c# 5 , below, can guarded with:
var title = person.title == null ? null : person.title.toupper(); now title variable null instead of throwing exception. c# 6 introduces shorter syntax this:
var title = person.title?.toupper(); this result in title variable being null, , call toupper not made if person.title null.
of course, still have check title null or use null condition operator null coalescing operator (??) supply default value:
// regular null check int titlelength = 0; if (title != null)     titlelength = title.length; // if title null, throw nullreferenceexception  // combining `?` , `??` operator int titlelength = title?.length ?? 0; 
Comments
Post a Comment