Ранее говорилось о том, что если в одном из методов списка делегата генерируется исключение, следующие методы не вызываются. Этого можно избежать, если обеспечить явный перебор всех методов в проверяемом блоке и обрабатывать возникающие исключения. Все методы, заданные в экземпляре делегата, можно
получить с помощью унаследованного метода GetInvocationList. Этот прием иллюстрирует листинг 10.6, представляющий собой измененный вариант листинга 10.1.
Листинг 10.6. Перехват исключений при вызове делегата
using System;
namespace ConsoleApplication1
{
delegate void Del(ref string s);
class Class1
{
public static void C001(ref string s)
{
Console.WriteLine("вызван метод С001");
string temp = "";
for (int i = 0; i < s.Length; ++i)
{
if (s[i] == 'o' || s[i] == '0') temp += '0';
else if (s[i] == 'l') temp += 'l';
else temp += s[i];
}
s = temp;
}
public static void Hack(ref string s)
{
Console.WriteLine("вызван метод Hack");
string temp = "";
for (int i = 0; i < s.Length; ++i)
if (i / 2 * 2 == i) temp += char.ToUpper(s[i]);
else temp += s[i];
s = temp;
}
public static void BadHack(ref string s)
{
Console.WriteLine("вызван метод BadHack");
throw new Exception(); // имитация ошибки
}
static void Main()
{
string s = "cool hackers";
|
|
Del d = new Del(C001); // создание экземпляра делегата
d += new Del(BadHack); // дополнение списка методов
d += new Del(Hack); // дополнение списка методов
foreach (Del fun in d.GetInvocationList())
{
try
{
fun(ref s); // вызов каждого метода из списка
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Exception in method " + fun.Method.Name);
}
}
Console.WnteLine("результат - " + s);
}
}
}
Результат работы программы:
вызван метод C001
вызван метод BadHack
Exception of type System.Exception was thrown.
Exception in method BadHack
вызван метод Hack
результат - C0001 hAcKeRs
В этой программе помимо метода базового класса GetInvocationList использовано свойство Method. Это свойство возвращает результат типа Method Info. Класс Method Info содержит множество свойств и методов, позволяющих получить полную информацию о методе, например его спецификаторы доступа, имя и тип возвращаемого значения. Мы рассмотрим этот интересный класс в разделе «Рефлексия» главы 12.