# Привязка аргументов строго типизированных функций

Для механизма [строго типизированных функций](https://workshop-guide.magicbyte.ru/mbsl-docs/modeli-vyzova-funkcii/strogo-tipizirovannye-funkcii) библиотека предоставляет также механизм привязки аргументов, что позволяет передать строго типизированную функцию с уже привязанной частью аргументов для дальнейшего вызова. Этот механизм представлен четыремя классами.

Механизм позволяет привязать значение **первого** аргумента строго типизированной функции и создать новую функцию, принимающую на один аргумент меньше.

Для строго типизированных действий используется семейство классов BindAction и BindActionRef. Основное отличие в том, что класс с суффиксом Ref держат сильную ссылку на аргумент (и, как следствие, не совместимы с примитивными типами вроде int, float и т.п.), а без - нет. Это необходимо для обхода бага движка, при котором вид ссылки не передаётся при передачи типа в аргумент шаблона.

```clike
//N - количество аргументов ПОСЛЕ привязки, а не в привязываемой функции
//ClosureType - тип привязываемого аргумента
class MBSL_BindActionN<Class ClosureType, Class Arg1, ... Class Arg(N-1)> : Managed
{
    static MBSL_TypedAction(N-1)<Arg1, ..., Arg(N-1)> Bind(MBSL_TypedAction<ClosureType, Arg1, ... Arg(N-1)> function, ClosureType closure);
}


class MBSL_BindActionNRef<Class ClosureType, Class Arg1, ... Class Arg(N-1)> : Managed
{
    static MBSL_TypedAction(N-1)<Arg1, ..., Arg(N-1)> Bind(MBSL_TypedAction<ClosureType, Arg1, ... Arg(N-1)> function, ClosureType closure);
}
```

Для строго типизированных действий используется семейство классов BindFunction и BindFunctionRef. Отличия между Ref и обычный аналогичны TypedAction.

```clike
//N - количество аргументов ПОСЛЕ привязки, а не в привязываемой функции
//ClosureType - тип привязываемого аргумента
class MBSL_BindFunctionN<Class ReturnType, Class ClosureType, Class Arg1, ... Class Arg(N-1)> : Managed
{
    static MBSL_TypedFunction(N-1)<ReturnType, Arg1, ..., Arg(N-1)> Bind(MBSL_TypedFunction<ReturnType, ClosureType, Arg1, ... Arg(N-1)> function, ClosureType closure);
}


class MBSL_BindActionNRef<Class ReturnType, Class ClosureType, Class Arg1, ... Class Arg(N-1)> : Managed
{
    static MBSL_TypedFunction(N-1)<ReturnType, Arg1, ..., Arg(N-1)> Bind(MBSL_TypedFunction<ReturnType, ClosureType, Arg1, ... Arg(N-1)> function, ClosureType closure);
}
```

**Важно:** созданные таким образом функции уже не ссылаются на оригинальный объект, на которой ссылалась строго типизированная функция. Они автоматически генерируются как сильные функции и ссылаются на специальный промежуточный объект, поэтому не рекомендуется изменять их тип на слабые, иначе они могут стать невалидными из-за уничтожения промежуточного объекта. Фактически, тип их ссылки на оригинальный объект фиксируется в момент привязки оригинальной строго типизированной функции.&#x20;

Ниже приведён пример привязки аргумента строго типизированной функции:

```clike
class Example : Managed
{
    ref MBSL_TypedFunction2<int, int, int> _Sum = MBSL_TypedFunction2<int, int, int>.Weak(this, "Sum");
    int Sum(int a, int b)
    {
        return a+b;
    }
}

Example e = new Example();
MBSL_TypedFunction1<int, int> addFive = MBSL_BindFunction1<int, int, int>.Bind(e._Sum, 5);
int r = addFive.Invoke(7); //r = 12
MBSL_TypedFunction0<int> twoPlusFive = MBSL_BindFunction0<int, int>.Bind(addFive, 2);
r = twoPlusFive.Invoke(); //r = 7
```
