Как цепочки делегатов .NET используются (пере) используются? - PullRequest
2 голосов
/ 12 марта 2009

Скажите, у меня есть следующий код C #:

Action a = TestMethod;
Action b = TestMethod;
Action c = b;
b += a;

Тесты показывают, что b - это не тот же экземпляр, что и c, поэтому очевидно, что оператор + создает новый экземпляр делегата. Это правильное предположение? Использует ли он внутренний экземпляр b или просто копирует информацию о методе / цели в новый экземпляр?

Кажется, я не могу найти реализацию оператора + для делегатов, класс Delegate, кажется, не содержит его.

Может кто-нибудь пролить свет на эту проблему?

Причина, по которой я спрашиваю, состоит в том, что я создаю некоторые классы, которые будут накладываться друг на друга как лук, а самый внешний слой вызовет внутренний слой, получит несколько делегатов и затем присоединит к ним больше методов Я просто обеспокоен тем, что это каким-то образом изменит делегатов, которые я получаю из внутреннего слоя, и в этом случае мне нужно будет возвращать копии / клоны, а не только внутренние ссылки.

Обратите внимание, что это полностью внутренний код для моей библиотеки, поэтому, хотя я знаю, что раздача таких внутренних структур данных, как правило, является плохой идеей, если я смогу сделать это безопасно с этими классами, я сделаю это. *

Ответы [ 2 ]

4 голосов
/ 12 марта 2009

Как говорит Кент, + = использует для Delegate.Combine, а - = использует Delegate.Remove. См. Мою статью о событиях / делегатах для получения дополнительной информации.

Важно то, что делегаты являются неизменными - вызов Combine / Remove не меняет делегата, которому вы его вызываете, - поэтому вам не нужно ничего клонировать. То же самое верно для всего, что вы делаете с делегатом: например, если вы получите список вызовов и измените содержимое возвращаемого массива, это не изменит того, что на самом деле делает делегат.

(Это похоже на поведение Стринга, если вы хотите по-другому об этом думать.)

4 голосов
/ 12 марта 2009

+= эквивалентно Delegate.Combine(). -= эквивалентно Delegate.Remove(). Каждый создает новый экземпляр Delegate и возвращает его.

...