我发现C#中的异常消息不能为空,并且在尝试此
之后 var ex = new Exception(null);
Console.WriteLine(ex.Message);
我收到以下消息:
抛出了类型'System.Exception'的异常。
但是,在这种情况下,
var ex = new Exception(string.Empty);
Console.WriteLine(ex.Message);
消息只是空的。
如何解释这个?你认为这是预期的行为吗?
答案 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