КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Знакомство с делегатамиВ .NET Framework у методов обратного вызова масса приложений. Например, зарегистрировав методы обратного вызова, можно получать самые разные уведомления: о необработанных исключениях, изменении состоянии окна, выборе элементов меню, изменениях файловой системы и завершении асинхронных операций. В неуправляемом C/C++ адрес функции — это всего лишь адрес в памяти, не несущий дополнительной информации. Он не позволяет узнать, ни сколько параметров ожидает функция, ни их тип или тип значения, возвращаемого функцией, ни правила вызова функции. Короче, в неуправляемом C/C++ функции обратного вызова не обеспечивают безопасность типов (хотя их отличает высокая скорость выполнения). В .NET Framework функции обратного вызова играют не менее важную и всеобъемлющую роль, чем в неуправляемом программировании для Windows. Однако в .NET Framework есть механизм делегатов, обеспечивающий безопасность типов. Вот как объявляют, создают и используют делегаты: using System; using System.Windows.Forms; using System.IO;
// Определяем тип-делегат; // экземпляры ссылаются на метод, который // принимает параметр типа Int32 и возвращает void
internal delegate void Feedback(Int32 value);
public sealed class Program { public static void Main() { StaticDelegateDemo(); InstanceDelegateDemo(); ChainDelegateDemo1(new Program()); ChainDelegateDemo2(new Program()); }
private static void StaticDelegateDemo() { Console.WriteLine("— Static Delegate Demo --"); Counter(1, 3, null); Counter(1, 3, new Feedback(Program.FeedbackToConsole)); Counter(1, 3, new Feedback(FeedbackToMsgBox)); // Префикс "Program." необязательный. Console.WriteLine(); }
private static void InstanceDelegateDemo() { Console.WriteLine("— Instance Delegate Demo —"); Program p = new Program(); Counter(1, 3, new Feedback(p.FeedbackToFile)); Console.WriteLine(); }
private static void ChainDelegateDemo1(Program p) { Console.WriteLine("— Chain Delegate Demo 1 —"); Feedback fb1 = new Feedback(FeedbackToConsole); Feedback fb2 = new Feedback(FeedbackToMsgBox); Feedback fb3 = new Feedback(p.FeedbackToFile);
Feedback fbChain = null; fbChain = (Feedback)Delegate.Combine(fbChain, fb1); fbChain = (Feedback)Delegate.Combine(fbChain, fb2); fbChain = (Feedback)Delegate.Combine(fbChain, fb3); Counter(1, 2, fbChain); Console.WriteLine(); fbChain = (Feedback)Delegate.Remove(fbChain, new Feedback(FeedbackToMsgBox)); Counter(1, 2, fbChain); }
private static void ChainDelegateDemo2(Program p) { Console.WriteLine("— Chain Delegate Demo 2 --"); Feedback fb1 = new Feedback(FeedbackToConsole); Feedback fb2 = new Feedback(FeedbackToMsgBox); Feedback fb3 = new Feedback(p.FeedbackToFile); Feedback fbChain = null; fbChain += fb1; fbChain += fb2; fbChain += fb3; Counter(1, 2, fbChain); Console.WriteLine(); fbChain -= new Feedback(FeedbackToMsgBox); Counter(1, 2, fbChain); }
private static void Counter(Int32 from, Int32 to, Feedback fb) { for (Int32 val = from; val <= to; val++) { // Если указаны какие-либо методы обратного вызова, вызываем их. if (fb != null) fb(val); } }
private static void FeedbackToConsole(Int32 value) { Console.WriteLine("Item=" + value); }
private static void FeedbackToMsgBox(Int32 value) { MessageBox.Show("Item=" + value); }
private void FeedbackToFile(Int32 value) { StreamWriter sw = new StreamWriter("Status", true); sw.WriteLine("Item=" + value); sw.Close(); } } Обратите внимание на объявление внутреннего делегата Feedback. В этом примере делегат задает сигнатуру метода обратного вызова. Здесь Feedback определяет метод, принимающий один параметр типа Int32 и возвращающий void. Класс Program определяет закрытый статический метод — Counter. Он перечисляет целые числа, находящиеся между параметрами from и to. Метод Counter также принимает параметр fb, который представляет собой ссылку на объект-делегат Feedback. Counter итеративно перечисляет целые числа, для каждого числа (если fb не равна null) вызывая метод обратного вызова (определенный в переменной fb). Методу обратного вызова передается значение обрабатываемого элемента и его номер. Метод обратного вызова может обрабатывать любой элемент как ему угодно.
|