In.NET, что такое внутренняя реализация делегата?

Я понимаю, что объявление делегата-это что-то вроде этого:

public delegate int PerformCalculation(int x, int y);

однако, должно быть больше происходит. Цель делегата-предоставить указатель на метод, и для этого вы инкапсулируете ссылку на метод в делегате.

в какой структуре содержится эта ссылка (внутренне в делегате)? Я также понимаю, что вы можете инкапсулировать ссылку на несколько методов в делегате. Это значит, что в делегате есть массив, который их содержит?

кроме того, какие методы определены в делегате и т. д. Что на самом деле происходит, когда вы объявляете делегата с кратким:

public delegate int PerformCalculation(int x, int y);

?

EDIT: некоторые разъяснения. При объявлении делегата, компилятор автоматически создает загерметизированная класс, который наследуется от System.Метода multicastdelegate для вас. Вы можете увидеть это, если посмотрите на свою сборку с ildasm. Такой аккуратный. В принципе, с помощью одного оператора вы получаете целый новый класс, созданный для вас во время компиляции, и он имеет всю необходимую функциональность.

2 ответов


все делегаты наследуют от


внутренне это ссылочный тип, очень похожий на класс. Расшифровано это выглядит так:

public /* delegate */ class PerformCalculation : MulticastDelegate {
    public PerformCalculation(object target, IntPtr method) {}
    public virtual void Invoke(int x, int y) {}
    public virtual IAsyncResult BeginInvoke(int x, int y, AsyncCallback callback, object state) {}
    public virtual void EndInvoke(IAsyncResult result) {}
}

Я оставил реализации этих членов пустыми, они фактически сопоставлены с кодом в CLR. Компилятор динамически генерирует подписи метода в зависимости от подписи объявления делегата. Обратите внимание на аргументы x и y. Компилятор JIT помогает вызвать конструктор, используя синтаксис += или -=, он знает адрес памяти делегата целевой метод. Компилятор автоматически генерирует цель значение аргумента, в зависимости от того, был ли целевой метод статическим или нет. Два аргумента сопоставляются с делегатом (многоадресной рассылки).Свойства цели и метода. Фактический экземпляр базового класса может быть делегатом или MulticastDelegate, в зависимости от того, сколько целевых объектов было подписано.

много секретного соуса происходит здесь.