Прежде всего, я думаю, что я знаю, что происходит, но я подумал, что подниму этот вопрос здесь для некоторого обсуждения и выясню, есть ли у кого-нибудь "ответ" на этот вопрос, кроме того, о чем я думаю. Потому что для меня это не совсем понятно.
Я обнаружил, что при создании журнала ошибок для исключений я делал это, и оно не работало:
catch( Exception ex )
{
LogException( ex.Message );
if ( !string.IsNullOrEmpty( ex.InnerException.Message ) )
{
LogInnerException( ex.InnerException.Message );
}
}
и вот, когда я запускаю это, я часто получаю исключение NullReferenceException. А?
Я проверяю на ноль, верно?
Теперь я должен использовать это:
if ( ex.InnerException != null && !string.IsNullOrEmpty( ex.InnerException.Message )
но это кажется нелогичным, а также контрпродуктивным. Потому что, черт возьми, если я сделаю это:
if ( !string.IsNullOrEmpty( null ) )
Это не доставляет мне никаких проблем. И если ex.InnerException равно null, то, конечно, ex.InnerException.Message равно null, верно?
Видимо, нет.
Я написал полное консольное приложение, которое воспроизводит это. Если вы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace stringisnullorempty
{
class Program
{
static void Main( string[] args )
{
if ( !string.IsNullOrEmpty( null ) )
{
Console.WriteLine( "Ha ha ha, right...." );
}
MyBClass bClass = new MyBClass();
bClass.BClassName = "Some B Class Name";
if ( !string.IsNullOrEmpty( bClass.AClass.AString ) ) //<== Exception occurs here.
{
Console.WriteLine( bClass.AClass.AString );
}
}
}
public class MyAClass
{
private string aString;
public string AString
{
get
{
return aString;
}
set
{
aString = value;
}
}
private int aValue;
public int AValue
{
get
{
return aValue;
}
set
{
aValue = value;
}
}
public MyAClass() { }
}
public class MyBClass
{
private MyAClass aClass;
public MyAClass AClass
{
get
{
return aClass;
}
set
{
aClass = value;
}
}
private string bClassName;
public string BClassName
{
get
{
return bClassName;
}
set
{
bClassName = value;
}
}
public MyBClass() { }
}
}
Я думаю, что происходит то, что код обрабатывает ex.InnerException.Message, прежде чем пытаться обработать IsNullOrEmpty. Поскольку ex.InnerException имеет значение null, мы получаем исключение при попытке доступа к ex.InnerException.Message.
Мне интересно, нужна ли мне полная проверка? Будет ли ex.InnerException! = Null достаточно. Если у нас есть внутреннее исключение, будет ли с ним всегда связано сообщение?
Спасибо.