Tuesday 15 February 2011

c# - What is a NullReferenceException and how do I fix it? -



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 it?

what cause? bottom line

you trying utilize 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 create can lead nullreferenceexception.

more specifically

the runtime throwing nullreferenceexception always means same thing: trying utilize reference. reference not initialized (or was initialized, no longer initialized).

this means reference null, , cannot access members through null reference. simplest case:

string foo = null; foo.toupper();

this throw nullreferenceexception @ sec line, because can't phone 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 programme 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 next programme flow way can find location instance should not null, , why isn't set.

examples

some mutual 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 look 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.

indirect public class person { public int age { get; set; } } public class book { public person author { get; set; } } public class illustration { public void foo() { book b1 = new book(); int authorage = b1.author.age; // never initialized author property. // there no person age from. } }

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. // utilize 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 client customer; private void form1_load(object sender, eventargs e) { client customer = new customer(); customer.name = "john"; } private void button_click(object sender, eventargs e) { messagebox.show(customer.name); } }

this can solved next convention prefix fields underscore:

private client _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 homecoming empty model (or model property) controller, exception occurs when views accesses it:

// controller public class restaurant:controller { public actionresult search() { homecoming view(); // forgot provide model here. } } // razor view @foreach (var restaurantsearch in model.restaurantsearch) // throws. { } <p>@model.somepropertyname</p> <!-- throws --> wpf command creation order , events

wpf controls created during phone 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 illustration :

<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 (ie: listing label1 before combobox1, ignoring issues of design philosophy, @ to the lowest degree 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 homecoming null in case. aware of that.

ways avoid explicitly check null, , ignore null values.

if expect reference null, can check beingness null before accessing instance members:

void printname(person p) { if (p != null) { console.writeline(p.name); } } explicitly check null, , provide default value.

methods calls expect homecoming instance can homecoming null, illustration when object beingness sought cannot found. can take homecoming default value when case:

string getcategory(book b) { if (b == null) homecoming "unknown"; homecoming b.category; } explicitly check null method calls , throw custom exception.

you can throw custom exception, grab in calling code:

string getcategory(string booktitle) { var book = library.findbook(booktitle); // may homecoming null if (book == null) throw new booknotfoundexception(booktitle); // custom exception homecoming book.category; } use debug.assert if value should never null, grab problem before exception occurs.

when know during development method maybe can, never should homecoming null, can utilize debug.assert() break possible when occur:

string gettitle(int knownbookid) { // know should never homecoming null. var book = library.getbook(knownbookid); // exception occur on next line instead of @ end of method. debug.assert(book != null, "library didn't homecoming book known book id."); // other code ... homecoming book.title; // never throw nullreferenceexception in debug mode. }

though check will not end in release build, causing throw nullreferenceexception 1 time 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 utilize // coalesce operator: serviceimpl.frobpowerlevel = frobpowerlevel ?? 5; } use null status operator: ?. (available in c# 6 , vb.net 14):

this called safe navigation or elvis (after shape) operator. if look 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 phone 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 beingness null, , phone call toupper not made if person.title null.

of course, still have check title null or utilize null status 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;

c# .net vb.net null nullreferenceexception

No comments:

Post a Comment