c# - Qu'est-ce qu'une exception de référence de Null, et comment le corriger

Mots clés : c#.netvb.netnullnullreferenceexceptionc#

meilleur 5 Réponses c# - Qu'est-ce qu'une exception de référence de Null, et comment le corriger

vote vote

91

string foo = null; foo.ToUpper(); 
ref1.ref2.ref3.member 
var r1 = ref1; var r2 = r1.ref2; var r3 = r2.ref3; r3.member 
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; // You never initialized the Author property.                                        // there is no Person to get an Age from.     } } 
Book b1 = new Book  {     Author = { Age = 45 }  }; 
Book b1 = new Book(); b1.Author.Age = 45; 
public class Person  {     public ICollection<Book> Books { get; set; } } public class Book  {     public string Title { get; set; } } 
Person p1 = new Person  {     Books = {          new Book { Title = "Title1" },          new Book { Title = "Title2" },     } }; 
Person p1 = new Person(); p1.Books.Add(new Book { Title = "Title1" }); p1.Books.Add(new Book { Title = "Title2" }); 
int[] numbers = null; int n = numbers[0]; // numbers is null. There is no array to index. 
Person[] people = new Person[5]; people[0].Age = 20 // people[0] is null. The array was allocated but not                    // initialized. There is no Person to set the Age for. 
long[][] array = new long[1][]; array[0][0] = 3; // is null because only the first dimension is yet initialized.                  // Use array[0] = new long[2]; first. 
Dictionary<string, int> agesForNames = null; int age = agesForNames["Bob"]; // agesForNames is null.                                // There is no Dictionary to perform the lookup. 
public class Person  {     public string Name { get; set; } } var people = new List<Person>(); people.Add(null); var names = from p in people select p.Name; string firstName = names.First(); // Exception is thrown here, but actually occurs                                   // on the line above.  "p" is null because the                                   // first element we added to the list is null. 
public class Demo {     public event EventHandler StateChanged;          protected virtual void OnStateChanged(EventArgs e)     {                 StateChanged(this, e); // Exception is thrown here                                 // if no event handlers have been attached                                // to StateChanged event     } } 
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);     } } 
    private Customer _customer; 
public partial class Issues_Edit : System.Web.UI.Page {     protected TestIssue myIssue;      protected void Page_Load(object sender, EventArgs e)     {         if (!IsPostBack)         {              // Only called on first load, not when button clicked              myIssue = new TestIssue();          }     }              protected void SaveButton_Click(object sender, EventArgs e)     {         myIssue.Entry = "NullReferenceException here!";     } } 
// if the "FirstName" session value has not yet been set, // then this line will throw a NullReferenceException string firstName = Session["FirstName"].ToString(); 
// Controller public class Restaurant:Controller {     public ActionResult Search()     {         return View();  // Forgot the provide a Model here.     } }  // Razor view  @foreach (var restaurantSearch in Model.RestaurantSearch)  // Throws. { }      <p>@Model.somePropertyName</p> <!-- Also throws --> 
<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> 
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e) {     label1.Content = comboBox1.SelectedIndex.ToString(); // NullReferenceException here!! } 
var myThing = someObject as Thing; 
List<int> list = null;     foreach(var v in list) { } // NullReferenceException here 
foreach (var node in myData.MyXml.DocumentNode.SelectNodes("//Data")) 
void PrintName(Person p) {     if (p != null)      {         Console.WriteLine(p.Name);     } } 
string GetCategory(Book b)  {     if (b == null)         return "Unknown";     return b.Category; } 
string GetCategory(string bookTitle)  {     var book = library.FindBook(bookTitle);  // This may return null     if (book == null)         throw new BookNotFoundException(bookTitle);  // Your custom exception     return book.Category; } 
string GetTitle(int knownBookID)  {     // You know this should never return null.     var book = library.GetBook(knownBookID);        // Exception will occur on the next line instead of at the end of this method.     Debug.Assert(book != null, "Library didn't return a book for known book ID.");      // Some other code      return book.Title; // Will never throw NullReferenceException in Debug mode. } 
DateTime? appointment = null; Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now)); // Will display the default value provided (DateTime.Now), because appointment is null.  appointment = new DateTime(2022, 10, 20); Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now)); // Will display the appointment date, not the default 
IService CreateService(ILogger log, Int32? frobPowerLevel) {    var serviceImpl = new MyService(log ?? NullLog.Instance);      // Note that the above "GetValueOrDefault()" can also be rewritten to use    // the coalesce operator:    serviceImpl.FrobPowerLevel = frobPowerLevel ?? 5; } 
var title = person.Title.ToUpper(); 
var title = person.Title == null ? null : person.Title.ToUpper(); 
var title = person.Title?.ToUpper(); 
// regular null check int titleLength = 0; if (title != null)     titleLength = title.Length; // If title is null, this would throw NullReferenceException      // combining the `?` and the `??` operator int titleLength = title?.Length ?? 0; 
int[] myIntArray = null; var i = 5; int? elem = myIntArray?[i]; if (!elem.HasValue) Console.WriteLine("No value"); 
public IEnumerable<Frob> GetFrobs(FrobFactory f, int count) {     for (int i = 0; i < count; ++i)     yield return f.MakeFrob(); } ... FrobFactory factory = whatever; IEnumerable<Frobs> frobs = GetFrobs(); ... foreach(Frob frob in frobs) { ... } 
// DON'T DO THIS public IEnumerable<Frob> GetFrobs(FrobFactory f, int count) {    if (f == null)        throw new ArgumentNullException("f", "factory must not be null");    for (int i = 0; i < count; ++i)       yield return f.MakeFrob(); } 
// DO THIS public IEnumerable<Frob> GetFrobs(FrobFactory f, int count) {    // No yields in a public method that throws!    if (f == null)         throw new ArgumentNullException("f", "factory must not be null");    return GetFrobsForReal(f, count); } private IEnumerable<Frob> GetFrobsForReal(FrobFactory f, int count) {    // Yields in a private method    Debug.Assert(f != null);    for (int i = 0; i < count; ++i)         yield return f.MakeFrob(); } 
vote vote

89

Dim reg As CashRegister ... TextBox1.Text = reg.Amount         ' NRE 
Dim reg As New CashRegister        ' [New] creates instance, invokes the constructor  ' Longer, more explicit form: Dim reg As CashRegister = New CashRegister 
Private reg As CashRegister         ' Declare   ... reg = New CashRegister()            ' Create instance 
Private reg As CashRegister '...  Public Sub New()    '...    Dim reg As New CashRegister End Sub 
Private arr as String() 
Private arr as String() = New String(10){} ' or Private arr() As String = New String(10){}  ' For a local array (in a procedure) and using 'Option Infer': Dim arr = New String(10) {} 
Dim myDbl As Double() = {1.5, 2, 9.9, 18, 3.14} Dim myDbl = New Double() {1.5, 2, 9.9, 18, 3.14} Dim myDbl() = {1.5, 2, 9.9, 18, 3.14} 
Private myDoubles As Double() = {1.5, 2, 9.9, 18, 3.14} 
Dim arrFoo(5) As Foo  For i As Integer = 0 To arrFoo.Count - 1    arrFoo(i).Bar = i * 10       ' Exception Next 
For i As Integer = 0 To arrFoo.Count - 1     arrFoo(i) = New Foo()         ' Create Foo instance     arrFoo(i).Bar = i * 10 Next 
Dim FooList As New List(Of Foo)     ' List created, but it is empty Dim f As Foo                        ' Temporary variable for the loop  For i As Integer = 0 To 5     f = New Foo()                    ' Foo instance created     f.Bar =  i * 10     FooList.Add(f)                   ' Foo object added to list Next 
Private myList As List(Of String) .. myList.Add("ziggy")           ' NullReference 
myList = New List(Of String)  ' Or create an instance when declared: Private myList As New List(Of String) 
Public Class Foo     Private barList As List(Of Bar)      Friend Function BarCount As Integer         Return barList.Count     End Function      Friend Sub AddItem(newBar As Bar)         If barList.Contains(newBar) = False Then             barList.Add(newBar)         End If     End Function 
Public Sub New         ' Constructor     ' Stuff to do when a new Foo is created...     barList = New List(Of Bar) End Sub 
Public Sub New()     ' Creates another barList local to this procedure      Dim barList As New List(Of Bar) End Sub 
Dim da As OleDbDataAdapter Dim ds As DataSet Dim MaxRows As Integer  con.Open() Dim sql = "SELECT * FROM tblfoobar_List" da = New OleDbDataAdapter(sql, con) da.Fill(ds, "foobar") con.Close()  MaxRows = ds.Tables("foobar").Rows.Count      ' Error 
Dim ds As New DataSet 
ds = New DataSet da = New OleDBDataAdapter(sql, con) da.Fill(ds, "Employees")  txtID.Text = ds.Tables("Employee").Rows(0).Item(1) txtID.Name = ds.Tables("Employee").Rows(0).Item(2) 
If ds.Tables(0).Rows.Count > 0 Then     txtID.Text = ds.Tables(0).Rows(0).Item(1)     txtID.Name = ds.Tables(0).Rows(0).Item(2) End If 
If da.Fill(ds, "Employees") > 0 Then... 
Dim da As New OleDb.OleDbDataAdapter("SELECT TICKET.TICKET_NO,         TICKET.CUSTOMER_ID, ... FROM TICKET_RESERVATION AS TICKET INNER JOIN         FLIGHT_DETAILS AS FLIGHT ... WHERE [TICKET.TICKET_NO]= ...", con) Dim ds As New DataSet da.Fill(ds)  If ds.Tables("TICKET_RESERVATION").Rows.Count > 0 Then 
If ds.Tables(0).Rows.Count > 0 Then 
If myFoo.Bar.Items IsNot Nothing Then    ... 
If (myFoo IsNot Nothing) AndAlso     (myFoo.Bar IsNot Nothing) AndAlso     (myFoo.Bar.Items IsNot Nothing) Then     .... 
myBase.myNodes(3).Layer.SubLayer.Foo.Files.Add("somefilename") 
myWebBrowser.Document.GetElementById("formfld1").InnerText = "some value" 
Dim cmd5 As New SqlCommand("select Cartons, Pieces, Foobar " _      & "FROM Invoice where invoice_no = '" & _      Me.ComboBox5.SelectedItem.ToString.Trim & "' And category = '" & _      Me.ListBox1.SelectedItem.ToString.Trim & "' And item_name = '" & _      Me.ComboBox2.SelectedValue.ToString.Trim & "' And expiry_date = '" & _      Me.expiry.Text & "'", con) 
Dim expiry As DateTime         ' for text date validation If (ComboBox5.SelectedItems.Count > 0) AndAlso     (ListBox1.SelectedItems.Count > 0) AndAlso     (ComboBox2.SelectedItems.Count > 0) AndAlso     (DateTime.TryParse(expiry.Text, expiry) Then      '... do stuff Else     MessageBox.Show(...error message...) End If 
Public Class Form1      Private NameBoxes = New TextBox(5) {Controls("TextBox1"), _                    Controls("TextBox2"), Controls("TextBox3"), _                    Controls("TextBox4"), Controls("TextBox5"), _                    Controls("TextBox6")}      ' same thing in a different format:     Private boxList As New List(Of TextBox) From {TextBox1, TextBox2, TextBox3 ...}      ' Immediate NRE:     Private somevar As String = Me.Controls("TextBox1").Text 
Sub Form_Load(..._    '...    Dim name As String = NameBoxes(2).Text        ' NRE    ' ...    ' More code (which will likely not be executed)    ' ... End Sub 
Public Class Form1      Private myFiles() As String = Me.OpenFileDialog1.FileName & ...     Private dbcon As String = OpenFileDialog1.FileName & ";Jet Oledb..."     Private studentName As String = TextBox13.Text 
' Module level declaration Private NameBoxes as TextBox() Private studentName As String  ' Form Load, Form Shown or Sub New: ' ' Using the OP's approach (illegal using OPTION STRICT) NameBoxes = New TextBox() {Me.Controls("TextBox1"), Me.Controls("TestBox2"), ...) studentName = TextBox32.Text           ' For simple control references 
' Declaration Private NameBoxes As TextBox()  ' Initialization -  simple and easy to read, hard to botch: NameBoxes = New TextBox() {TextBox1, TextBox2, ...)  ' Initialize a List NamesList = New List(Of TextBox)({TextBox1, TextBox2, TextBox3...}) ' or NamesList = New List(Of TextBox) NamesList.AddRange({TextBox1, TextBox2, TextBox3...}) 
Private bars As New List(Of Bars)        ' Declared and created  Public Function BarList() As List(Of Bars)     bars.Clear     If someCondition Then         For n As Integer = 0 to someValue             bars.Add(GetBar(n))         Next n     Else         Exit Function     End If      Return bars End Function 
bList = myFoo.BarList() For Each b As Bar in bList      ' EXCEPTION       ... 
 bList = myFoo.BarList()  If bList IsNot Nothing Then... 
Dim dr As SqlDataReader Try     Dim lnk As LinkButton = TryCast(sender, LinkButton)     Dim gr As GridViewRow = DirectCast(lnk.NamingContainer, GridViewRow)     Dim eid As String = GridView1.DataKeys(gr.RowIndex).Value.ToString()     ViewState("username") = eid     sqlQry = "select FirstName, Surname, DepartmentName, ExtensionName, jobTitle,              Pager, mailaddress, from employees1 where username='" & eid & "'"     If connection.State <> ConnectionState.Open Then         connection.Open()     End If     command = New SqlCommand(sqlQry, connection)      'More code fooing and barring      dr = command.ExecuteReader()     If dr.Read() Then         lblFirstName.Text = Convert.ToString(dr("FirstName"))         ...     End If     mpe.Show() Catch  Finally     command.Dispose()     dr.Close()             ' <-- NRE     connection.Close() End Try 
For Each row As DataGridViewRow In dgvPlanning.Rows     If Not IsDBNull(row.Cells(0).Value) Then         ... 
If row.Cells(0) IsNot Nothing Then ... 
If (row.Cells(0) IsNot Nothing) AndAlso (IsDBNull(row.Cells(0).Value) = False) Then 
Dim getFoo = (From f In dbContext.FooBars                Where f.something = something                Select f).FirstOrDefault  If Not IsDBNull(getFoo) Then     If IsDBNull(getFoo.user_id) Then         txtFirst.Text = getFoo.first_name     Else        ... 
If getFoo IsNot Nothing Then... 
Dim chk As CheckBox  chk = CType(Me.Controls(chkName), CheckBox) If chk.Checked Then     Return chk End If 
If (chk IsNot Nothing) AndAlso (chk.Checked) Then ... 
dgvBooks.DataSource = loan.Books dgvBooks.Columns("ISBN").Visible = True       ' NullReferenceException dgvBooks.Columns("Title").DefaultCellStyle.Format = "C" dgvBooks.Columns("Author").DefaultCellStyle.Format = "C" dgvBooks.Columns("Price").DefaultCellStyle.Format = "C" 
dgvBooks.Columns(0).Visible = True 
xlWorkSheet = xlWorkBook.Sheets("sheet1")  For i = 0 To myDGV.RowCount - 1     For j = 0 To myDGV.ColumnCount - 1         For k As Integer = 1 To myDGV.Columns.Count             xlWorkSheet.Cells(1, k) = myDGV.Columns(k - 1).HeaderText             xlWorkSheet.Cells(i + 2, j + 1) = myDGV(j, i).Value.ToString()         Next     Next Next 
For Each r As DataGridViewRow in myDGV.Rows     If r.IsNewRow = False Then          ' ok to use this row 
My.Settings.FooBars.Add("ziggy")         ' foobars is a string collection 
If My.Settings.FooBars Is Nothing Then     My.Settings.FooBars = New System.Collections.Specialized.StringCollection End If 
vote vote

76

object o = null; DateTime d = (DateTime)o; 
<asp:Calendar runat="server" SelectedDate="<%#Bind("Something")%>" /> 
vote vote

64

if (myvar != null) {     // Go ahead and use myvar     myvar.property = ... } else {     // Whoops! myvar is null and cannot be used without first     // assigning it to an instance reference     // Attempting to use myvar here will result in NullReferenceException } 
vote vote

54

SqlConnection connection = null; connection.Open(); 

Questions similaires