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