17.委托
.NET框架使用委托delegate来提供回调函数机制。
{
private Object[] items;
public Set(int numItems)
{
items = new Object[numItems];
for (int i = 0; i < numItems; i++)
{
items[i] = i;
}
}
//定义了一个共有委托类型Feedback,委托表示一个回调方法签名,故Feedback委托表示一个接受3个参数,且返回值为void的回调方法
public void ProcessItems(Feedback feedback)
{
for (int item = 0; item < items.Length; item++)
{
if (feedback != null)
{
feedback(items[item],item+1,items.Length);
}
} //ProcessItems方法接受一个参数feedback,然后调用由feedback变量所指定的回调方法
}
}
1.使用委托回调静态方法
{
Set setofItems = new Set(5);
setofItems.ProcessItems(null);
//传递给feedback参数的值为null,不会调用任何回调方法
setofItems.ProcessItems(new Set.Feedback(/**//*method*/));
//构造一个委托对象,封装一个方法method,这使得该方法可以通过委托封装进行间接回调
Set.Feedback fb = null;
fb += new Set.Feedback(/**//*method1*/);
fb += new Set.Feedback(/**//*method2*/);
setofItems.ProcessItems(fb);
//委托链,所有回调的方法都必须接受相同参数,返回值类型
}
2.使用委托回调实例方法
与调用静态方法不同的是,回调实例方法需要构造一个对象
App appobj=new App();
setOfItems.ProcessItems(new Set.Feedback(appobj.FeedbackToFile));
18.异常
异常对象都包含一个描述字符串和一个堆栈踪迹。微软规定所有和CLS兼容的编程语言都必须能够抛出并捕获那些继承自System.Exception的异常类型。
void SomeMethod() {
try {
//需要异常恢复和资源清理的操作代码;或可能会抛出异常的代码
//单独一个try块是没有任何意义的
}
catch(异常筛选器exception filter) {
//异常恢复代码 ,出现异常时需要执行的响应代码
//异常筛选器本身是一个类型;代码执行时是自上而下搜索catch块的,应将更具体的异常放在上面,否则会产生个错误
}
finally {
//包含确保要执行的代码,一般是资源清理代码
//不管线程是否抛出异常,该代码块中的代码都能确保被执行
//一个try块并非必须要有一个finally块相关联,因为有时候try块中的代码并不需要任何清理工作;但一个try块最多只能有一个相关联的finally块
}
}
异常不是错误,它是对程序接口隐含假设的一种违反。这里的程序接口是指属性的数据类型,方法的参数,返回值等。通过抛出异常,一个方法可以通知它的调用程序它所做的假设被违反了。
如何正确使用异常?
a. 避免过多的finally块;C#提供了lock和using语句,是编译器自动产生try块和finally块,其中finally块就是清理代码,它们编译产生的结果是一样的。
b. 避免直接用System.Exception异常筛选器捕获所有异常,因为系统随时可能抛出StackOverflowException或OutOfMemoryException
c. 当异常无法修复时,回滚部分完成的操作