Skip to content

Commit c676e45

Browse files
committed
Реализованы делегаты
1 parent bfded29 commit c676e45

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

docs/delegate.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Делегаты
2+
3+
Делегаты в фреймворке ФИНТ позволяют создавать ссылки на методы объектов, реализуя механизм указателей на функции. Это достигается через автоматическую генерацию специальных методов с суффиксом "Ссылка" (например, `МойМетодСсылка`), которые возвращают объект класса `Действие`. Объект `Действие` инкапсулирует экземпляр объекта и имя метода, обеспечивая отложенный вызов с сохранением контекста. Делегаты поддерживают полиморфизм: в случае наследования вызывается реализация из дочернего класса.
4+
5+
## Введение
6+
7+
Делегаты заменяют лямбда-выражения или анонимные функции в среде строгой типизации OneScript, позволяя передавать поведение методов как параметры или хранить в свойствах. Они генерируются автоматически для всех экспортных методов классов во время инициализации фреймворка.
8+
9+
**Преимущества:**
10+
- Типобезопасность: Проверки типов параметров и возвращаемого значения на этапе выполнения.
11+
- Интеграция с ООП: Поддержка наследования и полиморфизма — делегаты от базового класса могут вызывать переопределенные методы в наследниках.
12+
- Гибкость: Передача методов в коллекции, использование в обработчиках событий.
13+
14+
Связанные механизмы: [Интерфейсы](interfaces.md) для контрактов методов, [Методы](methods.md) для объявления экспортных процедур/функций.
15+
16+
## Использование
17+
18+
1. **Создание ссылки:** Вызовите метод `ИмяМетодаСсылка()` на экземпляре объекта. Возвращается объект `Действие`.
19+
2. **Выполнение:** Для процедур — `Действие.Выполнить(параметры...)`; для функций — `Результат = Действие.Выполнить(параметры...)`.
20+
3. **Передача:** Делегаты можно хранить в свойствах (`&Действие Обработчик;`), передавать в методы или коллекции.
21+
4. **Проверки типов:** Фреймворк проверяет соответствие типов параметров и возвращаемого значения.
22+
23+
**Методы объекта `Действие`:**
24+
25+
| Метод | Параметры | Возврат | Описание |
26+
|-----------|--------------------|------------------|----------|
27+
| Выполнить | Аргументы метода | Результат (для функций) | Выполняет оригинальный метод с переданными аргументами. Для процедур — без возврата. |
28+
29+
**Примечание:** Делегаты привязаны к экземпляру объекта (`ЭтотОбъект`), поэтому полиморфизм достигается через наследование.
30+
31+
## Примеры
32+
33+
### Простой пример: Делегат для процедуры
34+
35+
В классе `ВходящийЗапрос` (из `fint_web`) объявлен экспортный метод `ВызовПроцедурыИзДелегата`. Фреймворк генерирует `ВызовПроцедурыИзДелегатаСсылка`.
36+
37+
```bsl
38+
ОбъектВходящегоЗапроса = ВходящийЗапрос.Создать(); // Создание экземпляра
39+
Действие = ОбъектВходящегоЗапроса.ВызовПроцедурыИзДелегатаСсылка(); // Получение делегата
40+
Действие.Выполнить("Привет из корня"); // Вызов: выводит сообщение через оригинальный метод
41+
```
42+
43+
### Пример: Делегат для функции
44+
45+
Аналогично для функции `ВызовФункцииИзДелегата` (возвращает строку).
46+
47+
```bsl
48+
ТекстИзДелегата = ОбъектВходящегоЗапроса.ВызовФункцииИзДелегатаСсылка().Выполнить(); // Вызов без параметров, результат в переменную
49+
Сообщить(ТекстИзДелегата); // Вывод: строка от оригинального метода
50+
```
51+
52+
## Ограничения
53+
54+
- **Только экспортные методы:** Делегаты генерируются исключительно для публичных (`Экспорт`) методов. Неэкспортные игнорируются.
55+
- **Привязка к экземпляру:** Делегат работает только с конкретным объектом. Хранение ссылки на уничтоженный объект приведет к ошибке выполнения.
56+
- **Типизация:** Параметры и возвращаемое значение проверяются динамически. Несоответствие вызовет исключение.
57+
- **Производительность:** Генерация и вызов через `Действие` добавляют overhead; используйте для динамических сценариев, не для hot paths.
58+
59+
> **Предупреждение:** Избегайте циклических ссылок с делегатами — может привести к утечкам памяти.

packagedef

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Описание.Имя("fint")
2-
.Версия("0.1.4")
2+
.Версия("0.1.5")
33
.Автор("Андрей Савадеров (Macegor)")
44
.АдресАвтора("[email protected]")
55
.АдресРепозитория("https://github.com/Macegor/fint")

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@
4444
- [Наследование](docs/inheritance.md)
4545
- [Интерфейсы](docs/interfaces.md)
4646
- [Перечисления](docs/enumeration.md)
47+
- [Делегаты](docs/delegate.md)

src/Классы/КонтейнерПакета.os

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,17 @@
622622
КонецЦикла;
623623

624624
Для Каждого Элемент Из ДанныеМетодовДляПерехватчиков Цикл
625+
625626
ДобавитьПерехватчикиКОбъекту(Элемент.Объект, Элемент.Декоратор, Элемент.ЛокальныйДекоратор, Элемент.Метод, Элемент.Генерируемый);
627+
628+
Если ТипЗнч(Элемент.Метод) = Тип("СтрокаТаблицыЗначений") И Элемент.Метод.Экспорт Тогда
629+
МетодДелегат = Новый Метод(Элемент.Метод.Имя + "Ссылка")
630+
.Публичный()
631+
.ТелоМетода(СтрШаблон("Возврат Новый Действие(ЭтотОбъект, ""%1"");", Элемент.Метод.Имя));
632+
633+
Элемент.Декоратор.Метод(МетодДелегат);
634+
КонецЕсли;
635+
626636
КонецЦикла;
627637

628638
Для Каждого Элемент Из ДанныеПодготовленныхДекораторов Цикл
@@ -1357,7 +1367,7 @@
13571367
Возврат "Функция Значение() Экспорт
13581368
| Возврат %1;
13591369
|КонецФункции";
1360-
1370+
13611371
КонецФункции
13621372

13631373
ДанныеГенерируемыхФункцийСвойств = Новый ТаблицаЗначений();

0 commit comments

Comments
 (0)