SORU
11 Ocak 2011, Salı


Bir NullReferenceException nedir ve nasıl düzeltebilirim?

Bazı kodlar var ve yürütür, ** 28 laf atar:

Nesne başvurusu bir nesnenin örneğine ayarlanmadı.

Bu, ve ben bu konuda ne yapabilirim? ne demek

CEVAP
11 Ocak 2011, Salı


Sebebi nedir?

Alt Satırda

null (veya VB.NET Nothing) bir şey kullanmak için çalışıyoruz. Bu ya null, ayarlamak ya da hiç bir şey için hiç de ayarlamak anlamına gelir.

Başka bir şey null etrafında geçti alır gibi. Eğer null"A", olabilir yöntem "B" geçti null . bu yöntem ^em>için"". Bir yöntem

Bu makalenin geri kalanında, daha ayrıntılı gider ve birçok programcı NullReferenceException neden hangi sıklıkla yaptığı hataları gösterir.

Daha Spesifik Olarak

Çalışma zamanı NullReferenceException atmaher zamanaynı şey anlamına gelir: bir referans kullanmak için çalışıyoruz. Başvuru başlatılamadı (ya daoldubaşlatıldı, ama hayıruzunbaşlatıldı).

Bu başvuru 37 ** null bir başvuru üzerinden erişemiyor üye olduğu anlamına gelir. En basit örnek:

string foo = null;
foo.ToUpper();

Bu string bir referans örnek yöntemi ToUpper() null işaret diyemezsin çünkü NullReferenceException ikinci bir çizgi atmak olacaktır.

Hata ayıklama

Nasıl NullReferenceException bir kaynağı buluyor musunuz? Bunun dışında size bakıyor durum kendini, çıkar atılmış tam olarak Yeri nerede oluşur, genel kurallar hata ayıklama Visual Studio uygulayın: stratejik noktalarını ve inspect your variables, ya da uçan fare isimlerini, açılış Hızlı İzle pencere veya kullanarak çeşitli hata ayıklama panelleri gibi Yerli ve Arabalar.

Eğer başvuru veya set değil nerede olduğunu öğrenmek istiyorsanız, sağ tıklayın ve adını girin ve "Tüm Kaynaklar". Sonra her bulduğu yerde bir kesme yeri ve ekli hata ayıklayıcısını ile programınızı çalıştırabilirsiniz. Her zaman hata ayıklayıcı sonları böyle bir kesme, ihtiyacın olup olmadığını belirlemek için beklediğiniz başvuru için boş olmayan, kontrol değişkeni ve emin olun bu puan için bir örnek, ne zaman bekliyorsun.

Program akışı bu yolu takip ederek, örnek null olmamalıdır ve düzgün değil neden konumunu bulabilirsiniz.

Örnekler

Bu durum bazı genel senaryolar:

Jenerik

ref1.ref2.ref3.member

Eğer ref1 veya ref2 ref3 veya boş ise, o zaman NullReferenceException alırsınız. Eğer sorunu çözmek istiyorsanız, o zaman daha basit eşdeğer bir ifadeyi yeniden yazarak boş olduğunu öğrenmek:

var r1 = ref1;
var r2 = r1.ref2;
var r3 = r2.ref3;
r3.member

Özellikle, HttpContext.Current.User.Identity.Name HttpContext.Current boş olabilir, ya da User özelliği boş olabilir, ya da Identity özelliği boş olabilir.

Dolaylı

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.
    }
}

Aynı iç içe geçmiş nesne başlatıcılar için geçerlidir:

Book b1 = new Book { Author = { Age = 45 } };

Sırada new anahtar kelime kullanılır, bu sadece yeni bir örneğini oluşturur Book ama yeni bir örnek Person, Author malıdır hala null.

Dizi

int[] numbers = null;
int n = numbers[0]; // numbers is null. There is no array to index.

Dizi Elemanları

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.

Pürüzlü Diziler

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.

Toplama/Liste/Sözlük

Dictionary<string, int> agesForNames = null;
int age = agesForNames["Bob"]; // agesForNames is null.
                               // There is no Dictionary to perform the lookup.

Değişken (Dolaylı/Ertelenmiş) Aralığı

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.

Olaylar

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
    }
}

Kötü Adlandırma Kuralları:

Eğer alanları yerliler farklı hazır, hiç alan başlatılmış olduğunu fark etmiş olabilirsiniz.

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);
    }
}

Bu Sözleşme, bir alt çizgi ile önek için aşağıdaki alanları ile çözülebilir

private Customer _customer;

Sayfa Yaşam Döngüsü ASP.NET :

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!";
    }
}

Oturum Değerleri ASP.NET

// if the "FirstName" session value has not yet been set,
// then this line will throw a NullReferenceException
string firstName = Session["FirstName"].ToString();

ASP.NET MVC görünüm modelleri boş

Boş bir model (ya da model özelliği) kumanda döndüğünüzde, istisna görüşlerini eriştiğinde oluşur:

// 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.
{
}

WPF Yaratılış Düzeni ve Olayları Kontrol

WPF denetimleri visual ağacında göründükleri sırada InitializeComponent çağrı sırasında oluşturulur. NullReferenceException erken oluşturulan olay işleyicileri ile kontrolleri, InitializeComponent sırasında ateş eden referans geç oluşturulan denetimleri vb. durumunda yükseltilecektir

Örneğin :

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

Burada comboBox1 label1 önce oluşturulur. Başvuru için comboBox1_SelectionChanged 77 girişimleri ** Eğer Henüz oluşturulmuş değil.

private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    label1.Content = comboBox1.SelectedIndex.ToString(); // NullReference here!!
}

XAML tanımlamalar sırası (örn: comboBox1 tasarım felsefesinin sorunları görmezden gelmek, en azından NullReferenceException burada. çözecek önce label1 Listeleme değiştirme


Yol Önlemek için

Açıkça* *82, kontrol ve null değerleri yoksayar.

Eğer başvuru bazen boş olmamı istiyorsan, örnek üyeleri erişmeden önce null varlık kontrol edebilirsiniz:

void PrintName(Person p) {
    if (p != null) {
        Console.WriteLine(p.Name);
    }
}

Açıkça null için kontrol edin ve varsayılan bir değer girin.

Yöntem bir örnek nesne aranan bulunamıyor örneğin null, geri dönmek için beklediğiniz çağırır. Bu durumda varsayılan bir değer döndürmek için seçebilirsiniz:

string GetCategory(Book b) {
    if (b == null)
        return "Unknown";
    return b.Category;
}

Açıkça yöntem çağrıları null kontrol edin ve özel bir istisna.

Ayrıca özel bir durum, sadece çağıran kodun içinde onu yakalamak için atmak

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;
}

Eğer bir değeri asla 91 ** sorun, durum daha erken yakalamak olmalıdır Debug.Assert kullanın.

Belki bir yöntem olabilir, ama aslında hiç null, dönmelidir gelişimi sırasında biliyorsanız Debug.Assert() ortaya çıktığında en kısa sürede kırmak için kullanabilirsiniz:

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.
}

114 ** book == null NullReferenceException tekrar atmak için neden serbest modunda zamanında olsa bu kontrol edin.

NULL değer türleri için GetValueOrDefault() null zaman varsayılan bir değer sağlamak için kullanın.

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

Null coalescing operator: ?? [C#] veya If() [VB].

null karşılaşıldığında varsayılan bir değer sağlamak için steno:

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;
}

Boş koşul operatörünü kullanın: ?. (C# 6 ve VB.NET 14 kullanılabilir):

Bu da bazen navigasyon ya da Elvis (şekil sonra güvenli) operatör denir. Eğer operatörün sol tarafındaki ifade ise null, sonra da sağ tarafında değerlendirilecek ve boş yerine döndü. Bu gibi durumlarda anlamına gelir:

var title = person.Title.ToUpper();

Eğer kişi bir adı var mı yoksa bu bir null değeri bir özellik ToUpper aramak için çalışıyor, çünkü bir özel durum oluşturur.

C# 5 ve altında, Bu ile korunuyor olabilir:

var title = person.Title == null ? null : person.Title.ToUpper();

Şimdi başlık değişken bir özel durum üretiliyor yerine boş olacaktır. C# 6 tanıtır bunun için kısa bir örnek:

var title = person.Title?.ToUpper();

Bu başlık değişken null olarak sonuçlanır ve ToUpper çağrısı person.Title null değildir.

Tabii ki, senhalanull title kontrol ya da birlikte boş birleşiyor operatörü (??) varsayılan bir değer girin: null koşul operatörünün kullanımı var

// 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;

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • GFX Tutorials

    GFX Tutorial

    12 AĞUSTOS 2013
  • Major FX

    Major FX

    6 HAZİRAN 2012
  • sghaff1

    sghaff1

    23 Mart 2009