Привет всем.
Сначала предыстория. Хотел было написать функцию с ref-параметрами (точно не знаю как они называются, но имею в виду ф-я, объявляемая внутри метода).
Дабы получилось нечто вроде:
def tmp=fun(i : ref int):bool
{
//lala
}
Не выйдет! И вот почему. Я залез в код, генерируемый рефлектором, и был сильно удивлён. Я полагал, что указатели на методы или функции — наследники MulticastDelegate.
Оказалось, что на каждую функцию генерируется класс, наследник внутреннего класса Function[n, r] (точнее, есть ещё Function2, Funcrion3 и т.д. — по числу параметров). И указатель на функцию есть ничто иное как экземпляр этого класса-наследника.
То есть код
def tmp=fun(i : int):bool
{
i>0;
}
Console.WriteLine(tmp(5));
преобразуется в
private sealed class tmpClass : Function[int, bool]
{
public override apply(i : int) : bool
{
i>0;
}
}
mutable tmp==tmpClass();
Console.WriteLine(tmp.apply(5));
Хотя, на мой взгляд, более логично было бы сделать так:
private delegate tmpHandler(i : int) : bool;
private sealed class tmpClass
{
public apply(i : int) : bool
{
i>0;
}
}
mutable tmp==tmpHandler(tmpClass().apply);
Console.WriteLine(tmp.Invoke(5));
Тогда бы можно было и ref-, и, соответственно, out-параметры делать. Да и сами указатели на ф-и выглядели более человечно с точки зрения .NET.
PS: ф-я внутри метода может использовать локальные переменные метода, и тогда генерируется немного больше кода. Но на суть проблемы это не влияет.
В человечишке все должно быть прекрасненьким: и одёжка, и душенка, и мордочка, и мыслишки.