(Para obtener información sobre el nuevo asistente de excepción en Visual Studio 2017, consulte el final de esta respuesta)
Considere este código:
String s = null;
Console.WriteLine(s.Length);
Esto arrojará un NullReferenceExceptionen la segunda línea y querrá saber por qué .NET no le dice sque era nulo cuando se lanzó la excepción.
Para entender por qué no obtiene esa información, debe recordar que no es la fuente C # la que se ejecuta, sino IL:
IL_0001: ldnull
IL_0002: stloc.0 // s
IL_0003: ldloc.0 // s
IL_0004: callvirt System.String.get_Length
IL_0009: llamar a System.Console.WriteLine
Es el callvirtcódigo de operación el que arroja el NullReferenceExceptiony lo hace cuando el primer argumento en la pila de evaluación es una referencia nula (la que se cargó usando ldloc.0).
Si .NET debería poder decir que sfue una referencia nula, debería de alguna manera rastrear que el primer argumento en la pila de evaluación se originó en el formulario s. En este caso, es fácil para nosotros ver que es snulo, pero ¿qué pasa si el valor es un valor de retorno de otra llamada de función y no se almacena en ninguna variable? De todos modos, este tipo de información no es lo que desea rastrear en una máquina virtual como la máquina virtual .NET.
Para evitar este problema, le sugiero que realice una verificación nula de argumentos en todas las llamadas a métodos públicos (a menos que, por supuesto, permita la referencia nula):
public void Foo(String s) {
if (s == null)
throw new ArgumentNullException("s");
Console.WriteLine(s.Length);
}
Si se pasa nulo al método, obtiene una excepción que describe con precisión cuál es el problema (que ses nulo).
Cuatro años después, Visual Studio 2017 ahora tiene un nuevo asistente de excepción que intentará decir qué es nulo cuando NullReferenceExceptionse lanza un. Incluso es capaz de brindarle la información requerida cuando es el valor de retorno de un método que es nulo:

Tenga en cuenta que esto solo funciona en una compilación DEBUG.