Что именно является делегатом? - PullRequest
3 голосов
/ 25 января 2012

Я использую делегаты (Actions, WaitCallbacks, Funcs) довольно часто, но я пытаюсь лучше понять, что именно они.

У меня довольно хорошее понимание объектов по сравнению с ссылочными типами и т. Д. И где они хранятся в куче по сравнению со стеком?

В основном - я пытаюсь понять использование делегатов с точки зрения производительности. У кого-нибудь есть ссылки на ресурсы или, может быть, хорошее объяснение?

Кроме того, что именно это «события»? Как они относятся к делегатам? Являются ли они просто списком делегатов, которые перебираются?

Ответы [ 4 ]

2 голосов
/ 25 января 2012

Все, что было сказано до сих пор, верно. Вот как это работает под прикрытием: делегат имеет два поля: указатель на исполняемый код и поле типа объекта, представляющего этот параметр (вы можете передать делегат методу экземпляра).

Когда вы вызываете этот делегат, центральный процессор извлекает указатель на код в регистр и затем «вызывает» этот указатель. Инструкции вызова не должны использовать постоянные значения. Процессор может перейти к переменной области в памяти.

События - это просто делегаты плюс два метода-обертки для присоединения нового делегата или удаления существующего. Смущает то, что у делегатов есть третье поле, которое я пропустил: делегат! делегаты формируют связанный список. Это называется MulticastDelegate, и это мерзость. Когда вы вызываете делегата, это может привести к вызову нескольких методов с одинаковой подписью. Вот как работают события. Событие - это отдельное поле типа делегата.

Теперь забудьте о многоадресных делегатах, потому что они не имеют отношения на практике.

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

Делегаты могут быть двух типов, насколько я понимаю:

  • «указатели на связанный с экземпляром метод», что означает, что делегат содержит экземпляр объекта подписывающегося объекта иметод в классе объекта для вызова.Если у меня есть MyClass.Handler (), и я создаю пять экземпляров MyClass и создаю 5 делегатов для каждого экземпляра, указывая на метод Handler (), то каждый делегат будет иметь один и тот же указатель метода, но свой экземпляр объекта.

  • Указатели статических методов, например, делегаты статических методов, в этом случае контекст объекта не требуется.

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

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

Делегат - это элемент языка C #, который позволяет ссылаться на метод. Если бы вы были программистом на C или C ++, это звучало бы знакомо, потому что делегат - это просто указатель на функцию . Однако разработчики, которые использовали другие языки, вероятно, задаются вопросом: «Зачем мне нужна ссылка на метод?». Ответ сводится к тому, чтобы дать вам максимальную гибкость для реализации любой функциональности, которую вы хотите во время выполнения.

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

Делегаты - это структуры данных, которые представляют функции - тип возвращаемого значения и аргументы (типы и числа).Любой метод, который соответствует типу возврата делегата и подписи, может быть назначен такому делегату.

С точки зрения производительности - это дополнительный уровень абстракции, но небольшой.Это не то, что вы, вероятно, заметите.

...