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
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;
Tanımsız başvuru/çözülmemiş bir dış si...
Bit shift (bit-shift) operatörleri ned...
Node.js amacı modülü nedir.ihracat ve ...
Vim kaydı nasıl kapatılır nedir?...
Vı nasıl bütün bir dosya girinti düzel...