建议68:从System.Exception或其他常见的根基异常中派生异常
微软建议:从System.Exception或其他常见根基异常之一派生异常。在Visual Studio中输入Exception,然后按快捷键Tab,VS会自动创建一个自界说异常类:
[Serializable] public class MyException : Exception { // // For guidelines regarding the creation of new exception types, see // ?url=http://www.mamicode.com/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp // and // ?url=http://www.mamicode.com/library/en-us/dncscol/html/csharp07192001.asp // public MyException() { } public MyException(string message) : base(message) { } public MyException(string message, Exception inner) : base(message, inner) { } protected MyException( SerializationInfo info, StreamingContext context) : base(info, context) { } }
这是一个标准的自界说异常,它同时报告你,你所创建的异常必需是可序列化的,因为你必需保证异常是可以穿越AppDomain界限的。
如果你需要从一个根基异常派生自界说异常,则类似这样声明:
[Serializable] public class MyException : IOException
一般来说,以上的描述已经满足你对付自界说异常的普通需求,但是另一个需求是,你也许会想要格局化异常的Message。好比,为一个测验系统设计一个自界说的加密异常:PaperEncryptException,我们需要格局化一些异常信息。所以,必需重写(override)异常类的Message属性,,如下所示:
[Serializable] public class PaperEncryptException : Exception, ISerializable { private readonly string _paperInfo; public PaperEncryptException() { } public PaperEncryptException(string message) : base(message) { } public PaperEncryptException(string message, Exception inner) : base(message, inner) { } public PaperEncryptException(string message, string paperInfo) : base(message) { _paperInfo = paperInfo; } public PaperEncryptException(string message, string paperInfo, Exception inner) : base(message, inner) { _paperInfo = paperInfo; } protected PaperEncryptException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } public override string Message { get { return base.Message + " " + _paperInfo; } } public override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Args", _paperInfo); base.GetObjectData(info, context); } }
PaperEncryptException与MyException对比,有两个明显的差别:
1)实现了接口ISerializable。
2)重写了要领GetObjectData。
这是因为我们给PaperEncryptException界说了一个新的字段_paperInfo。为了确保新界说的字段也能被序列化,必需要让异常类型实现ISerializable接口,并且需要将字段插手到GetObjectData要领的SerializationInfo参数中。
测试代码如下:
try { throw new PaperEncryptException("加密试卷掉败", "学生ID:123456"); } catch (PaperEncryptException err) { Console.WriteLine(err.Message); }
输出:
“加密试卷掉败 学生ID:123456”