C# 自訂異常
來源:互聯網
上載者:User
C# 自訂異常問題的提出,在開發應用程式的過程當中,.net 為我們提供了嚴密的異常捕獲的方法,使應用程式能夠健壯的運行”如果自訂異常繼承自Exception ,缺點在這裡:如果異常直接繼承自Exception ,我們的代碼可能會跑出一個應用程式根本吧知道的新異常類型。這很可能成為一個未處理異常而導致應用程式中斷。這種行為很容易發生,以為我們違反了一個隱含的假設,而應用程式有沒有提供任何補救措施。如果我們捕獲了這個新的異常,然後便忽略它並繼續執行應用程式,同樣可能產生不可預期的結果。“以上摘自 Jeffrey Richter 的《Microsoft.NET.架構程式設計》下面提供了代碼的實現//--------------------------------------------------------------------------- // File: DiskFullException.cs //// Description: 自子定義異常// History: // 06/24/2011////--------------------------------------------------------------------------- using System;using System.IO;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Soap;//允許DiskFullExceptio 的執行個體可以執行個體化[Serializable]sealed class DiskFullException : Exception,ISerializable{//三個共有構造器public DiskFullException():base()//調用基類的構造器{}public DiskFullException(string message):base(message)//調用基類的構造器{}public DiskFullException(string message,Exception innerException):base(message,innerException)//調用基類的構造器{}//定義了一個私人欄位private string diskpath;//頂一個唯讀屬性,改屬性返回新定義的欄位public string DiskPath{get {return diskpath;}}//重新共有屬性Message,將新定義的欄位包含在異常的資訊文本中public override string Message{get{string msg=base.Message;if(diskpath!=null)msg+=Environment.NewLine+"Disk Path:"+diskpath;return msg;}}//因為定義了至少新的欄位,所以要定義一個特殊的構造器用於還原序列化//由於該類是密封類,所以該構造器的訪問限制被定義為私人方式。否則,該構造器//被定義為受保護方式private DiskFullException(SerializationInfo info,StreamingContext context):base(info,context)//讓基類還原序列化其內定義的欄位{diskpath=info.GetString("DiskPath");}//因為定義了至少一個欄位,所以要定義序列化方法void ISerializable.GetObjectData(SerializationInfo info,StreamingContext context){//序列化新定義的每個欄位info.AddValue("DiskPath",diskpath);//讓基類序列化其內定義的欄位base.GetObjectData(info,context);}//定義額外的構造器設定新定義的欄位public DiskFullException(string message,string diskpath):this(message)//調用另外一個構造器{this.diskpath=diskpath;}public DiskFullException(string message,string diskpath,Exception innerException):this(message,innerException){this.diskpath=diskpath;}}//下面的代碼測試異常的序列化class App{static void Main(){//構造一個DiskFullException 對象,並對其序列化DiskFullException e=new DiskFullException("The diks volume is full",@"c:\");FileStream fs=new FileStream(@"Test",FileMode.Create);IFormatter f=new SoapFormatter();f.Serialize(fs,e);fs.Close();//還原序列化DiskFullException 對象,並查看它的欄位fs=new FileStream(@"Test",FileMode.Open);e=(DiskFullException)f.Deserialize(fs);fs.Close();Console.WriteLine("Type:{1}{0} DiskPath:{2}{0} Message:{3}",Environment.NewLine,e.GetType(),e.DiskPath,e.Message);Console.Read();}}