1. 程式人生 > >【轉】編寫高質量代碼改善C#程序的157個建議——建議68:從System.Exception或其他常見的基本異常中派生異常

【轉】編寫高質量代碼改善C#程序的157個建議——建議68:從System.Exception或其他常見的基本異常中派生異常

base 信息 crypt 滿足 需要 sys sdn private exc

建議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
        //    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
// and // http://msdn.microsoft.com/library/default.asp?url=/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”

轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技

【轉】編寫高質量代碼改善C#程序的157個建議——建議68:從System.Exception或其他常見的基本異常中派生異常