На что указывает делегат? - PullRequest
11 голосов
/ 25 февраля 2012

Я прочитал, что ссылочный тип содержит ссылку на фактический объект, который может храниться в управляемой куче.Когда метод «назначен» на ссылочную переменную делегата, на какую память ссылается ссылка?Как этот блок памяти связан с действительным кодом функции?

Ответы [ 4 ]

14 голосов
/ 25 февраля 2012

Давайте разберем простой пример:

using System;
class Program
{
    delegate bool MyFilter(int x);

    bool IsOdd(int x)
    {
        return x % 2 == 1;
    }

    static void Main()
    {
        MyFilter f = new Program().IsOdd;
        Console.WriteLine(f(5));
    }
}

Что делает компилятор?Давайте начнем с этой строки:

delegate bool MyFilter(int x);

Компилятор генерирует тип , который выглядит примерно так:

class MyFilter : MulticastDelegate
{
    public MyFilter(Object thisRef, IntPtr method);
    public bool Invoke(int x);
    // BeginInvoke(), EndInvoke() - Let's ignore those
}    

Тип MyFilter имеет конструктор, который принимает двапараметры: IntPtr для тела метода, чтобы вызвать, и Объект, для которого этот метод должен быть вызван.Метод Invoke () для типа MyFilter вызывает фактический делегат.

Теперь давайте посмотрим, что происходит в методе Main ().Компилятор перепишет его примерно так:

    static void Main()
    {
        MyFilter f = new MyFilter(new Program(), addressof(Program.IsOdd));
        Console.WriteLine(f.Invoke(5));
    }

Конечно, addressof не является действительным оператором C #, но вы можете себе представить, что он возвращает адрес тела для переданного метода.Кроме того, я не обсуждал различные другие темы, связанные с делегатами, такие как цепочка (это функция, предоставляемая базовым классом MulticastDelegate), но, надеюсь, я рассмотрел ваш вопрос.

Подводя итог, опорные точки делегатак объекту, который реализует метод Invoke, который соответствует подписи делегата.Объект отслеживает указатель на метод, который необходимо вызвать, а также целевой объект, для которого вызывается метод (если метод не является статическим).

0 голосов
/ 25 февраля 2012

Делегат фактически содержит два адреса - адрес метода и адрес объекта. Это довольно интересно, и несколько патентов, связанных с делегатами, были присуждены Хелсбергу http://www.google.com/patents/US6185728

Это очень эффективно. В интервью Хелсберг указал, что он может быть более эффективным, чем диспетчеризация VTBL (поскольку это прямой указатель на функцию). В простейших случаях это буквально косвенный вызов. * например 1006 *

 jmp *%eax

В целом, для выполнения делегата требуется 4 инструкции .

0 голосов
/ 25 февраля 2012

Не давая слишком сложного ответа, он указывает (ссылается) на фактический блок памяти, где хранится метод.

0 голосов
/ 25 февраля 2012

На самом деле существует два типа делегатов: Делегат и MulticastDelegate . Это абстрактные классы, унаследованные от фактического экземпляра delegate. Я бы порекомендовал прочитать эти классы, так как они содержат гораздо больше (точных) деталей, чем я объяснил здесь, но для краткой версии:

Хотя я не уверен на 100%, как именно работает реализация, самый простой способ представить объект Delegate - это object и MethodInfo, что является типом отражения для конкретного метода. Причина того, что тип Delegate является абстрактным, заключается в том, что метод Invoke зависит от параметров метода.

Аналогично, MulticastDelegate содержит несколько Delegate объектов, каждый из которых указывает на отдельную комбинацию object / MethodInfo. Это позволяет использовать систему event, в которой один event вызывает многократные вызовы методов.

Возвращаясь к деталям реализации, когда вы определяете делегат, он создает унаследованный класс от MulticastDelegate с помощью метода Invoke, также object может быть null для статических методов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...