Почему метод Invoke созданного класса делегата является виртуальным? - PullRequest
8 голосов
/ 28 сентября 2011

Я видел в CLR через C # и в статье codeproject Делегат за кулисами , что когда компилятор C # видит это

public delegate void MyDelegate(int intValue);

фактически генерирует что-то вроде этого

class MyDelegate : System.MulticastDelegate
{
    public virtual void Invoke(Int32 intValue);

    ...
}

Вопрос в том, почему метод Invoke является виртуальным ? Может ли этот сгенерированный тип делегата быть унаследованным? С точки зрения CLR выглядит так, как может. Но почему? Почему бы не сгенерировать запечатанный класс, чтобы не было наказания за поиск виртуальных методов во время выполнения?

Ответы [ 2 ]

1 голос
/ 29 сентября 2011

Вот интересная цитата из Эрика Липперта о наследовании в .NET:

меня иногда спрашивают "а как может тип значения, такой как int, который 32 бита памяти, не больше, не меньше, возможно, наследовать от объекта? размер объекта в памяти превышает 32 бита; у него есть синхронизация блок и таблица виртуальных функций и все такое прочее. " Видимо, многие люди думают, что наследование имеет какое-то отношение с тем, как значение выкладывается в памяти. Но как ценность заложена в память - это деталь реализации, а не договорное обязательство наследственные отношения!

В .NET существует ряд «специальных» унаследованных типов: System.ValueType, System.Enum, System.Void и System.Delegate, среди прочих, я уверен.

Взглянув на внутреннюю часть System.Delegate с помощью Reflector.NET, я вижу несколько таких звонков:

[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
internal static extern MulticastDelegate InternalAlloc(RuntimeType type);

Я подозреваю, что мы имеем дело с другой деталью реализации, которая не требует, чтобы делегаты использовали те же виртуальные справочные таблицы, которые нужны virtual методам.

1 голос
/ 29 сентября 2011

Это печатание типа «крякающий как утка».Подобный тип ввода, который делает System.Int32, тип значения, производный от ValueType, ссылочным типом.Не имеет смысла, нелегально в C #, но на самом деле ведет себя так.Реальная реализация метода Invoke делегата скрыта в CLR и представляет собой статическую функцию, написанную на C ++.

Но, конечно, аннотирование его как виртуального имеет некоторый смысл, потому что ведет себя как виртуальныйметод.Реальный код, который выполняется, не является фиксированным, как это происходит с невиртуальным методом класса.Еще сложнее понять, какой должна быть правильная модель для делегата, привязанного к статическому методу.Виртуальный метод, который статичен?

Это просто виртуальная утка.

Чтение указателей функций, используемых в C, может помочь вам получить лучшую ментальную модель для делегатов.Делегат - это указатель на функцию с включенными колоколами, он также может хранить целевой объект.В C # отсутствует синтаксис, чтобы выразить это по-другому.

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