空消息的异常

时间:2011-12-15 15:32:22

标签: c# exception

我发现C#中的异常消息不能为空,并且在尝试此

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

我收到以下消息:

  

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

但是,在这种情况下,

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

消息只是空的。

如何解释这个?你认为这是预期的行为吗?

4 个答案:

答案 0 :(得分:5)

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

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

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

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

修改

此行为也记录在the remarks for the Message property中:“如果没有为当前实例的构造函数提供消息,系统将提供使用当前系统区域性格式化的默认消息。”

我查看了CLI规范和C#规范,并且我没有发现Message有一个非null返回值的要求,所以我想这支持了这种行为是框架设计决策的观点。 / p>

答案 1 :(得分:3)

实际上构造函数不需要字符串,你绝对可以使用null。这是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作为消息,则会抛出本地化字符串,例如“类型'System.Exception'的异常。”将用作消息。这意味着 - 仍然存在您的异常,而不是另一个,但它的属性Message从构造函数返回另一个(计算的)值而不是null。

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

答案 2 :(得分:2)

string.Empty不为空,它是""的常量。

您的第一个示例是提供默认消息,第二个示例是空字符串

答案 3 :(得分:0)

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

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