首先,我想我知道发生了什么,但我想我会在这里提出这个问题进行讨论,看看是否有人对此有“答案”,而不是我的想法。因为,这对我来说并不完全有意义。
我发现在为异常创建错误日志时,我正在这样做并且它不起作用:
catch( Exception ex )
{
LogException( ex.Message );
if ( !string.IsNullOrEmpty( ex.InnerException.Message ) )
{
LogInnerException( ex.InnerException.Message );
}
}
你瞧,当我运行它时,我经常会得到一个 NullReferenceException。嗯?
我正在检查null,对吗?
现在,我必须使用这个:
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() { }
}
}
我认为正在发生的是代码在尝试处理 IsNullOrEmpty 之前处理 ex.InnerException.Message。由于 ex.InnerException 为空,我们在尝试访问 ex.InnerException.Message 时遇到异常。
我想知道,我需要完整的检查吗?ex.InnerException != null 是否足够。如果我们有一个内部异常,我们是否总是有与之关联的消息?
谢谢。