Мне было трудно придумать хороший способ сформулировать этот вопрос, поэтому позвольте мне попытаться объяснить на примере:
Предположим, у меня есть интерфейс. Для простоты я скажу, что интерфейс IRunnable
, и он предоставляет один метод, Run
. (Это не реально; это только пример.)
Теперь, предположим, у меня есть какой-то ранее существующий класс, назовем его Cheetah
, который я не могу изменить. Он существовал до IRunnable
; Я не могу заставить реализовать мой интерфейс. Но я хочу использовать его , как будто он реализует IRunnable
- предположительно, потому что у него есть метод Run
или что-то подобное. Другими словами, я хочу иметь возможность иметь код, который ожидает IRunnable
и будет работать с Cheetah
.
ОК, так что я всегда мог написать CheetahWrapper
сделку. Но позабавьте меня и позвольте мне написать что-нибудь более гибкое - как насчет RunnableAdapter
?
Я представляю определение класса примерно так:
public class RunnableAdapter : IRunnable {
public delegate void RunMethod();
private RunMethod Runner { get; set; }
public RunnableAdapter(RunMethod runner) {
this.Runner = runner;
}
public void Run() {
Runner.Invoke();
}
}
Достаточно просто, верно? Итак, после этого я смогу сделать звонок вот так:
Cheetah c = new Cheetah();
RunnableAdapter ra = new RunnableAdapter(c.Run);
А теперь, вуаля: у меня есть объект, который реализует IRunner
и в его сердцах Cheetah
.
Мой вопрос таков: если это мое Cheetah
выпадет из области видимости в какой-то момент и достигнет точки, где оно обычно будет собирать мусор ... не так ли? Или это свойство RunnableAdapter
объекта Runner
представляет собой ссылку на исходный Cheetah
, так что оно не будет собрано? Я, конечно, хочу, чтобы эта ссылка оставалась действительной, поэтому в основном мне интересно, достаточно ли приведенного выше определения класса или необходимо будет сохранить ссылку на базовый объект (например, через какое-то частное свойство UnderlyingObject
), просто чтобы предотвратить сборка мусора.