(Aby uzyskać informacje o nowym pomocniku wyjątków w programie Visual Studio 2017, zobacz koniec tej odpowiedzi)
Rozważ ten kod:
String s = null;
Console.WriteLine(s.Length);
Spowoduje to wrzucenie znaku NullReferenceExceptionw drugiej linii i chcesz wiedzieć, dlaczego .NET nie powie Ci, że był sto null, kiedy wyjątek został zgłoszony.
Aby zrozumieć, dlaczego nie dostajesz tej informacji, powinieneś pamiętać, że to nie źródło C # jest wykonywane, ale raczej IL:
IL_0001: ldnull
IL_0002: stloc.0 // s
IL_0003: ldloc.0 // s
IL_0004: callvirt System.String.get_Length
IL_0009: wywołaj System.Console.WriteLine
Jest to callvirtkod operacji, który rzuca NullReferenceExceptioni robi to, gdy pierwszy argument na stosie wartościowania jest odwołaniem zerowym (tym, który został załadowany przy użyciu ldloc.0).
Jeśli .NET miałby być w stanie stwierdzić, sże było to odwołanie zerowe, powinien w jakiś sposób śledzić, że pierwszy argument na stosie ocen pochodzi z formularza s. W tym przypadku łatwo nam zauważyć, że jest sto wartość zerowa, ale co by było, gdyby wartość była wartością zwracaną z innego wywołania funkcji i nie była przechowywana w żadnej zmiennej? W każdym razie tego rodzaju informacje nie są tym, co chcesz śledzić na maszynie wirtualnej, takiej jak maszyna wirtualna .NET.
Aby uniknąć tego problemu, sugeruję, abyś sprawdzał argumenty null we wszystkich wywołaniach metod publicznych (chyba że oczywiście pozwolisz na zerowe odwołanie):
public void Foo(String s) {
if (s == null)
throw new ArgumentNullException("s");
Console.WriteLine(s.Length);
}
Jeśli do metody zostanie przekazana wartość null, otrzymasz wyjątek, który dokładnie opisuje, na czym polega problem (czyli sjest zerowy).
Cztery lata później program Visual Studio 2017 ma teraz nowego pomocnika wyjątków, który spróbuje określić, co jest null, gdy NullReferenceExceptionzostanie zgłoszony. Jest nawet w stanie podać wymagane informacje, gdy jest to wartość zwracana metody, która ma wartość null:

Zauważ, że działa to tylko w kompilacji DEBUG.