(Para obter informações sobre o novo auxiliar de exceção no Visual Studio 2017, consulte o final desta resposta)
Considere este código:
String s = null;
Console.WriteLine(s.Length);
Isso lançará um NullReferenceExceptionna segunda linha e você deseja saber por que o .NET não informa sque era nulo quando a exceção foi lançada.
Para entender por que você não consegue essa informação, você deve se lembrar de que não é a fonte C # que executa, mas IL:
IL_0001: ldnull
IL_0002: stloc.0 // s
IL_0003: ldloc.0 // s
IL_0004: callvirt System.String.get_Length
IL_0009: chame System.Console.WriteLine
É o callvirtopcode que lança o NullReferenceExceptione faz isso quando o primeiro argumento na pilha de avaliação é uma referência nula (aquela que foi carregada usando ldloc.0).
Se o .NET for capaz de dizer que se trata de suma referência nula, ele deve, de alguma forma, rastrear que o primeiro argumento na pilha de avaliação se originou s. Nesse caso, é fácil para nós ver que é snulo, mas e se o valor for um valor de retorno de outra chamada de função e não estiver armazenado em nenhuma variável? De qualquer forma, esse tipo de informação não é o que você deseja acompanhar em uma máquina virtual como a máquina virtual .NET.
Para evitar esse problema, sugiro que você execute a verificação de argumento nulo em todas as chamadas de método público (a menos, é claro, que você permita a referência nula):
public void Foo(String s) {
if (s == null)
throw new ArgumentNullException("s");
Console.WriteLine(s.Length);
}
Se null for passado para o método, você obterá uma exceção que descreve precisamente qual é o problema (isto sé, null).
Quatro anos depois, o Visual Studio 2017 agora tem um novo auxiliar de exceção que tentará dizer o que é nulo quando um NullReferenceExceptioné lançado. Ele pode até mesmo fornecer as informações necessárias quando for o valor de retorno de um método nulo:

Observe que isso só funciona em um build DEBUG.