C# 定制异常
在应用程序中,有时也可以从这个基类中派生自己的异常类,并使用它们,而不是使用标准的异常。这样就可以把更具体的信息发送给捕获该异常的代码,让处理异常的捕获代码更有针对性。例如,可以给异常类添加一个新属性,以便访问某些底层信息,这样异常的接收代码就可以做出必要的改变,或者仅给出异常起因的更多信息。
给CardLib添加定制异常
为演示定制异常的用法,最好通过升级CardLib项目来说明。目前,如果试图访问索引小于0或大于51的扑克牌,Deck.GetCard()方法就会抛出一个标准的.NET异常,但下面改为使用一个定制异常。
首先需要在BeginningCSharp7\Chapterl3目录中创建一个新的类库项目Chl3CardLib,像以前一样把类从 ChI2CardLib中复制过来,并把名称空间改为Chl3CanlLib。接着定义该异常。方法是使用在新类文件 CardOutOfRangeException.cs中定义的一个新类,这个新类是使用Project | Add Class命令添加到Chl3CardLib 项目中的(这段代码包含在Chl3CardLib\CardOutOfRangeException.cs文件中):
public class CardOutOfRangeException : Exception
{
private Cards deckContents;
public Cards DeckContents
{
get { return deckContents; }
}
public CardOutOfRangeException(Cards sourceDeckContents)
:base(uThere are only 52 cards in the deck.")
{
deckContents = sourceDeckContents;
}
}
这个类的构造函数需要使用Cards类的一个实例,它允许通过DeckContents属性来访问这个Cads对象,为Exception基类构造函数提供合适的错误信息,使该错误信息可以通过类的Message属性得到。
接着在Deck.cs中添加抛出该异常的代码,替换原来的标准异常(这段代码包含在Chl3CardLib\Deck.cs文件中):
public Card GetCard(int cardNum)
{
if (cardNum >= 0 && cardNum <= 51)
return cards[cardNum];
else
throw new CardOutOfRangeException(cards.Clone() as Cards);
}
CardOutOfRangeException类的DeckContents属性是通过对Deck对象的当前内容(其形式是一个Cards对象)进行深度复制来初始化的。这表示,此时的内容是异常抛出时的内容,所以随后对Deck内容的修改不会丢失这些信息。
要进行测试,使用下面的客户端代码(这段代码包含在Chl3CardClientVProgram.cs文件中):
Deck deckl = new Deck{);
try
{
Card myCard = deckl.GetCard(60);
}
catch (CardOutOfRangeException e)
{
WriteLine(e.Message);
WriteLine(e.DeckContents[0]);
}
ReadKey();
添加对 Chl3CardLib.cm、using static System.Console 和 using Chi3CardLib 的引用后,执行代码,结果如图所示。
其中捕获代码把异常的Message属性写到屏幕上。我们还通过DeckContents显示了Cards对象中的第一张牌,以证明可以通过定制的异常对象来访问Cards集合。
点击加载更多评论>>