异常与空消息

问题描述:

我发现异常消息不能在C#空,并试图此异常与空消息

var ex = new Exception(null); 
Console.WriteLine(ex.Message); 

我收到以下消息后:

类型的异常“的System.Exception '被抛出。

但是,在这种情况下,

var ex = new Exception(string.Empty); 
Console.WriteLine(ex.Message); 

的消息只是空的。

这是怎么解释的?你认为这是预期的行为?

+1

检查出“异常”与.NET反射器或Telerik JustDecompile ctor) – kol 2011-12-15 15:34:28

其他的答案(不包括从chopikadze答案)似乎是基于事实的误读。这两个例子都没有抛出异常。

相反,在第一个示例中,构造的异常ex正在提供消息,因为构造函数的消息参数的值为null。该消息是“类型'异常'System.Exception'被抛出”。

当对象引用为空时,有一些回退行为是一种相当普遍的做法,所以这就是“如何解释”。当然,是否“预期”取决于您的期望。

在处理异常过程中抛出异常可能会产生问题,因此框架设计人员必须选择这种行为来减少这种可能性。坦率地说,如果我们都必须承担异常信息可能为空的可能性,那将是一场噩梦。

编辑

行为也会记录在the remarks for the Message property:“如果没有消息被提供给构造当前情况下,系统将提供正在使用当前系统区域性格式化的默认消息。”

我查看了CLI规范和C#规范,并且我没有发现消息具有非空返回值的要求,所以我认为支持该行为是框架设计决策的视图。

string.Empty不为空它是一个常数为""

你的第一个例子是给一个默认的消息,你的第二个例子是一个空字符串

+3

第一个示例是* not *产生空引用异常;构造的异常`ex`提供了一条消息,因为消息参数为空,所以对'ex.Message`的调用返回字符串'抛出'System.Exception'类型的异常。 – phoog 2011-12-15 15:41:32

+0

是的,它包装了一个空引用,因为他正试图向控制台写入一个空字符串.... – Maess 2011-12-15 15:55:14

+0

Console.WriteLine((string)null);不抛出异常。没有新的异常,Message属性只返回另一个字符串,而不是null – chopikadze 2011-12-15 15:57:58

是的,你正在使用的构造函数需要一个字符串。 String.Empty与null不同,因此它会抛出异常。

http://msdn.microsoft.com/en-us/library/system.exception.aspx

实际上构造函数不需要字符串,你绝对可以肯定使用null。这是Exception类的reflectored部分:“类型的异常‘System.Exception的’被抛出”

internal string _message; 

public Exception(string message) 
{ 
    this.Init(); 
    this._message = message; 
} 


private void Init() 
{ 
    this._message = null; 
    this._stackTrace = null; 
    this._dynamicMethods = null; 
    this.HResult = -2146233088; 
    this._xcode = -532462766; 
    this._xptrs = IntPtr.Zero; 
    this._watsonBuckets = null; 
    this._ipForWatsonBuckets = UIntPtr.Zero; 
    this._safeSerializationManager = new SafeSerializationManager(); 
} 

public virtual string Message 
{ 
    [SecuritySafeCritical] 
    get 
    { 
     if (this._message != null) 
     { 
      return this._message; 
     } 
     if (this._className == null) 
     { 
      this._className = this.GetClassName(); 
     } 
     return Environment.GetRuntimeResourceString("Exception_WasThrown", new object[] { this._className }); 
    } 
} 

所以,如果你使用null作为构造消息,本地化的字符串像将被用作消息。这意味着 - 仍然有你的异常,而不是另一个,但它的属性消息返回另一个(计算)的值,而不是构造函数的空值。

我认为它是由设计(也许是在另一个地方使用)定义的Exception.Message应该始终不为空。因此,如果我们想让开发人员使用Exception类的默认构造函数(例如,用于反射或稍后允许填充属性),但我们也希望Message始终不为空 - 我们应该使用某些东西来包装Message。我认为,消息使用的可能位置之一是在发生异常之后显示的默认对话框。这种方式可以使用只是消息属性,而不是检查 - 是消息属性等于空等