Возможно, это вопрос семантики, но, возможно, нет, поэтому я спрашиваю: есть ли заметная разница в следующих 2 фрагментах?
public Parent()
{
Child newChild = new Child();
newChild.RequestSpecialEvent += (sender, e) =>
{
newChild.DoMagic();
}
}
или
public Parent()
{
Child newChild = new Child();
newChild.RequestSpecialEvent += (sender, e) =>
{
((Child)sender).DoMagic();
}
}
ОчевидноеРазница заключается в том, что вариант 1 сам ссылается на себя, тогда как вариант 2 выполняет приведение объекта.С точки зрения производительности, я ожидаю, что приведение будет более дорогим.
Тем не менее, я предполагаю, что в варианте 1 технически это «Parent», который содержит ссылку на «newChild» (через делегат, определенный в Parent), поэтому, даже если newChild пропадает (newChild = null или что-то подобное), объект newChild не может быть собран сборщиком мусора (gc'ed), потому что Parent определил делегат, который все еще присоединен к нему.newChild может быть только gc'ed, когда Parent в конечном счете уходит.
Однако, в варианте 2, Parent никогда не создает такую «жесткую ссылку» на newChild, поэтому, когда происходит newChild = null, это действительно может быть gc 'немедленно.
Я предпочитаю вариант 1 из-за его краткости и читабельности, но беспокоюсь, что вариант 2 будет лучше.Мысли?Правильна ли моя теория или нет?Есть ли альтернативный или более предпочтительный подход (со здравым смыслом) для объявления того же отношения слушателя событий с родительскими / дочерними классами?
Ответ на @StriplingWarrior:
ВЧто касается сбора мусора, я все еще немного скептически.Делегат ссылается на newChild, поэтому мне кажется, что newChild не может уйти, пока делегат не уйдет.Теперь делегат уйдет, если newChild уйдет ... но все равно newChild не сможет уйти, пока делегат не уйдет!Кажется круглым (почти).Похоже, это должно было бы произойти:
//newChild = null;
//This alone won't truly free up the newChild object because the delegate still
//points to the newChild object.
//Instead, this has to happen
newChild.RequestSpecialEvent = null; //destroys circular reference to newChild
newChild = null; //truly lets newChild object be gc'd
Или, может быть, сказав 'newChild = null;'только newChild.RequestSpecialEvent перестает указывать на делегата, что позволяет делегату уходить, а затем позволяет newChild уходить?Может быть, я только что заговорил сам в свой ответ.:)