adr*_*nks 5 c# exception-handling exception
在处理自定义异常时,我通常从Exception继承,然后将一些字段/属性添加到我的异常类中以存储一些额外的信息:
public class MyException : Exception
{
public int ErrorCode{get;set;}
public MyException()
{}
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,该ErrorCode值存储在异常中,这意味着我必须将其添加到并且如果从SerializationInfo受保护的构造函数中的对象和重写的GetObjectData方法中退出.
获取键/值对的集合,这些键/值对提供有关异常的其他用户定义信息.
如果我将错误代码存储在其中Data,它将由Exception类(根据Reflector)为我序列化,这意味着我的异常类现在看起来像:
public class MyException : Exception
{
public int ErrorCode
{
get {return (int) Data["ErrorCode"];}
set {Data["ErrorCode"] = value;}
}
public MyException()
{}
}
Run Code Online (Sandbox Code Playgroud)
这意味着虽然在处理错误代码的获取/设置方面还有一些工作要做(比如处理转换错误和错误代码可能不在字典中的情况),但我不必担心关于序列化/反序列化它.
这只是两种不同的方式来实现同样的事情,还是一种方式比另一种方式有明显的优势(除了我已经提到的那些)?
我会避免使用数据,因为它不受您的控制,例如某处的某些代码可能决定覆盖“ErrorCode”值。相反,使用该属性并实现序列化。我使用以下代码来测试所有自定义异常,以确保我已正确实现它们。
public static void TestCustomException<T>() where T : Exception
{
var t = typeof(T);
//Custom exceptions should have the following 3 constructors
var e1 = (T)Activator.CreateInstance(t, null);
const string message = "message";
var e2 = (T)Activator.CreateInstance(t, message);
Assert.AreEqual(message, e2.Message);
var innerEx = new Exception("inner Exception");
var e3 = (T)Activator.CreateInstance(t, message, innerEx);
Assert.AreEqual(message, e3.Message);
Assert.AreEqual(innerEx, e3.InnerException);
//They should also be serializable
var stream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(stream, e3);
stream.Flush();
stream.Position = 0;
var e4 = (T)formatter.Deserialize(stream);
Assert.AreEqual(message, e4.Message);
Assert.AreEqual(innerEx.ToString(), e4.InnerException.ToString());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
991 次 |
| 最近记录: |