Осматривая делегатов в C # и .NET в целом, я заметил некоторые интересные факты:
При создании делегата в C # создается класс, производный от MulticastDelegate
, с конструктором:
.method public hidebysig specialname rtspecialname instance
void .ctor(object 'object', native int 'method') runtime managed { }
Это означает, что он ожидает экземпляр и указатель на метод. И все же синтаксис построения делегата в C # предполагает, что у него есть конструктор
new MyDelegate(int () target)
, где я могу распознать int ()
как экземпляр функции (int *target()
будет указателем на функцию в C ++). Очевидно, что компилятор C # выбирает правильный метод из группы методов, определенной именем функции, и создает делегат. Итак, первый вопрос: откуда компилятор C # (точнее Visual Studio) выбирает эту сигнатуру конструктора? Я не заметил никаких особых атрибутов или чего-то, что могло бы сделать различие. Это какая-то магия компилятора / visualstudio? Если нет, допустима ли конструкция T (args) target
в C #? Мне не удалось получить что-либо с ним, чтобы скомпилировать, например .:
int () target = MyMethod;
недопустимо, поэтому делает что-либо с MyMetod
, например, вызов .ToString()
для него (ну, в этом есть некоторый смысл, поскольку технически это метод group , но я думаю, что должна быть возможность явно выбрать метод путем приведения, например, (int())MyFunction
. все это чисто волшебство компилятора? Глядя на конструкцию через рефлектор, выявляется еще один синтаксис:
Func CS $ 1 $ 0000 = новый Func (null, (IntPtr) Foo);
Это соответствует дизассемблированной подписи конструктора, но не компилируется!
Последнее интересное замечание: классы Delegate
и MulticastDelegate
имеют еще один набор конструкторов:
.метод семейства hidebysig specialname rtspecialname экземпляр
void .ctor (класс System.Type target, строка 'method') cil managed
Где происходит переход от указателя экземпляра и метода к типу и имени метода строки? Можно ли это объяснить ключевыми словами runtime managed
в сигнатуре пользовательского конструктора делегата, т. Е. Среда выполнения выполняет свою работу здесь?
РЕДАКТИРОВАТЬ : хорошо, так что я должен переформулировать то, что я хотел сказать этим вопросом. По сути, я предполагаю, что в построении делегата задействована не только магия C # компилятора / CLR, но и некоторая магия Visual Studio , поскольку Intellisense отключает новый синтаксис при предложении аргументов конструктора и даже скрывает один из них. (например, Reflector не использует этот синтаксис и конструктор, в этом отношении).
Мне было интересно, верно ли это утверждение, и имеет ли синтаксис экземпляра функции более глубокий смысл в C # или это просто какой-то постоянный формат, реализованный магической частью Visual Studio для ясности (что имеет смысл, так как выглядит неверным) C #)? Короче говоря, если я внедрял Intellisense, я должен сделать что-то магическое для делегатов или я мог бы создать предложение с помощью какого-нибудь умного механизма?
ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ : так что, по общему мнению, это действительно против магии. Видя другие примеры (см. Комментарий Марка Гравелла) такого поведения VS, я убедился, что это так.