我有一个TabControl,每个标签都包含一个TradeBookSetViewModel。由于Tradebook可以变得非常大,用户可以根据需要删除该书。
在DeleteBook()上,我只是从observablecollection中删除了TradeBookSetViewModel:
_bookSetViewModels.Remove(oldbook);
然后我创建一个新的emptyBook作为占位符并将其插入相同的选项卡位置。 Tab仍然看起来像握着tradeBook,但它实际上是空的。
为此,我从Unity容器中解析出一个新实例,并将DisplayBook从oldBook复制到emptyBook中。
BookSetViewModel emptyBook = _container.Resolve<BookSetViewModel>();
emptyBook.DisplayName = oldbook.DisplayName;
_bookSetViewModels.Insert(positionOfDisposedTab, emptyBook);
到目前为止一切顺利。
但后来我意识到emptyBook也需要Books属性。属性Books属于Dictionary<string, CustomClassItem>
类型因此我首先想到的是我可以做与DisplayName相同的事情。
emptyBook.Books = oldbook.Books;
但这不是说空书会引用旧书,因此旧书不能再被垃圾收集了吗?
也许我应该像这样克隆字典:
emptyBook.Books = book.Books.ToDictionary(entry => entry.Key, entry => entry.Value);
目标:在一天结束时,我需要将emptyBook中的Books属性设置为null,然后oldBook才能被垃圾回收。有什么想法吗?
答案 0 :(得分:1)
但这不是说空书会引用旧书,因此旧书不能再被垃圾收集了吗?
不,除非你还没有提到别的东西。
这里只有两个对象(emptyBook
和oldbook
),引用相同的Books
字典。这并没有在它们之间建立任何参考关系;每个人都无法了解对方。
只要{root>无法通过其他引用访问oldbook
,它就有资格进行垃圾回收。
答案 1 :(得分:1)
如果您的词典没有直接或间接的引用回到您的视图模型类,那么就没有问题。
emptyBook和oldBook都会引用同一个字典,但是传出引用不会停止垃圾收集,只有传入连接才会这样做。
答案 2 :(得分:0)
另外,我会考虑TabControl
的“美”,该用户可以始终只使用一个Tab 。考虑让一个View Model
,后面有多个Models
。根据所选的Tab
始终使用与模型集合相同的View Model
选项正确Tradebook
。在Tab selection changed
上,View Model
被分配到有效标签。
答案 3 :(得分:0)
Book
和本书指向的字典是两个独立的对象。一个只是引用另一个。
引用类的字段或属性不会创建对包含该字段或属性的类的引用。
如果存储对oldbook.DisplayName
的引用,则表示存储对字典对象的引用。您没有存储对Book
指向的oldbook
对象的引用。
当垃圾收集器运行时,它会看到您正在引用字典,并且不会收集它。它会看到您没有引用Book
,并会收集它。
这当然假定您实际上并未在其他任何地方引用Book
对象。如果没有类具有oldbook
称为属性或字段的对象,并且您已从任何容器中删除它,或者不再引用包含Book
的容器,那么它将是收集。