Як використовувати функції в ZennoPoster

Інколи хочеться просто писати код, який виконує роботу, і менше вникати в те, як саме ця робота виконується. Звичайно, що для цього є можливість створити свій клас і методи в загальному коді, після чого визивати їх в потрібний момент. Проте, часто зручніше використовувати узагальнені делегати (так, уже після самого слова делегати здається що буде складно).

Для того, щоб не страшити нікого словом делегат, я використовую слово функція. Мені здається, що воно також підходить під визначення того, що саме я хочу робити. А робити я хочу слідуюче – в одному блоці проєкту описую те, що хочу робити, а в іншому блоці мені потрібно мати можливість визивати цей код.

Значить в C# є три типи узагальнених делегатів, які підходять під вирішення моєї задачі. Поділяються вони по типу значення яке вони повертають.
Action – приймає на вхід параметри, просто виконується, і нічого не повертає
Predicate – приймає на вхід параметри, проводить порівняння і повертає тільки true або false
Func – приймає на вхід параметри, і повертає одне значення

Значить для того, щоб скористатись, потрібно написати сам код.

Приклад роботи з Action

В цьому прикладі просто буде виводитись повідомлення в лог, приймаючи на вхід текстовий рядок:

Action<string> ToLogText = (x) =>{
	project.SendInfoToLog(x);
};
ToLogText("Текст");

А в наступному прикладі на вхід можна подавати вже будь-який об’єкт, і він буде серіалізованим в json, після чого результат виведемо в лог ZennoPoster:

Action<object> ToLogJson = (x) =>{
	project.SendInfoToLog(Global.ZennoLab.Json.JsonConvert.SerializeObject(x,  Global.ZennoLab.Json.Formatting.None));
};
ToLogJson("Текст");

Інколи приходиться добавляти багато даних в один список, при чому приходиться думати про синхронізацію потоків – приблизно такий фрагмент позволяє вказати синхронізацію потоків один раз, а визивати цей код будь-де (випадок, коли список один і не хочеться вказувати його ім’я при кожному добавлені даних):

string list_name = "list";
Action<string> AddLine = (x) =>{
	lock(SyncObjects.ListSyncer){
		project.Lists[list_name].Add(x);
	}
};

AddLine("рядок з текстом");

А ось приклад, коли є необхідність передавати ще ім’я списку, щоб добавляти рядок в потрібний список безпечним способом (тобто з синхронізацією потоків):

Action<string, string> AddLine = (x, y) =>{
	lock(SyncObjects.ListSyncer){
		project.Lists[x].Add(y);
	}
};

string list_name = "list";
AddLine(list_name, "текст");

Приклад роботи з Predicate

Ось приклад C# коду, який об’являє предикат, який буде перевіряти пустий текстовий рядок чи ні повертаючи true коли пустий і false коли не пустий:

Predicate<string> CheckEmpty = (x) =>{
	return string.IsNullOrEmpty(x);
};

return CheckEmpty("---");

А ось приклад предиката, який порівнює число відносно 0 і повертає true тільки коли число більше 0:

Predicate<int> CheckX = (x) =>{
	return x > 0;
};

return CheckX(-5);

Такі фунції зручно використовувати, коли приходиться фільтрувати дані за допомогою LINQ з метою забрати з конструкції все лишнє для кращого розуміння послідовності виконання коду.

Приклад роботи з Func

Частенько буває так, що є необхідність передати аргументи в функцію, щось зробити з даними, і потім повернути вже результат в іншому вигляді. Для цього використовується узагальнений делегат Func.
Нижче приведений код на вхід одержує об’єкт, а на виході повертає текст у вигляді json:

Func<object, string> ToJson = (x) =>{
	return Global.ZennoLab.Json.JsonConvert.SerializeObject(x,  Global.ZennoLab.Json.Formatting.None);
};

return ToJson("об'єкт");

Тобто, конструкції коду, які можуть займати багато місця, і мішати писати код – можна оформляти у вигляді таких функцій, і вже їх визивати в своєму проєкті.

Переносимо функції між блоками через project.Context

Для того, щоб передати такий узагальнений делегат з одного блока проєкту в інший використовується контекст. Виглядає це приблизно так:

project.Context["ToLogText"] = ToLogText;
project.Context["CheckEmpty"] = CheckEmpty ;
project.Context["CheckX"] = CheckX;
project.Context["AddLine"] = AddLine;
project.Context["ToJson"] = ToJson;

Це я описані вище фунції добавив в контекст, і тепер в будь-якому іншому блоці я можу визивати їх:

project.Context["ToLogText"]("виводжу рядок в лог");

Мені здається, що використання цих узагальнених делегатів є зручним у багатьох випадках при написанні своїх проєктів. А так як сам код знаходиться в блоках проєкту, то до коду завжди є прямий доступ – дуже легко відтестувати, і у випадку помилок ZennoPoster виведе правильну помилку (покаже де саме сталась помилка).

Якщо ще не приходилось користуватись – рекомендую однозначно спробувати і використовувати в своїх проєктах.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *