Генерируемый код компилятором
От: BOleg Россия  
Дата: 24.08.07 15:50
Оценка:
Привет всем.

Сначала предыстория. Хотел было написать функцию с 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: ф-я внутри метода может использовать локальные переменные метода, и тогда генерируется немного больше кода. Но на суть проблемы это не влияет.
В человечишке все должно быть прекрасненьким: и одёжка, и душенка, и мордочка, и мыслишки.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.