我有一个包含这段代码的主要方法:
List<MyType> myList = openDialog();
调用 openDialog 会打开一个对话框,该对话框返回一个包含所选项目的列表,该对话框用于选择项目。
private List<MyType> openDialog()
{
MyView myView = new MyView();
MyViewModel myViewModel = new MyViewModel();
myView.DataContext = myViewModel;
myView.ShowDialog();
return myViewModel.Result;
}
myViewModel.Result 是一个集合,其中包含 View 中数据网格的选定项。
我的问题是,我如何返回 ViewModel 的 Result 属性,我不确定 myViewModel 是否会被垃圾收集器回收,因为它仍然有对它的引用。
为了避免这种情况,我这样做:
private List<MyType> openDialog()
{
MyView myView = new MyView();
MyViewModel myViewModel = new MyViewModel();
myView.DataContext = myViewModel;
myView.ShowDialog();
return new List<MyType>(myViewModel.Result);
}
在返回中,我正在创建一个新列表以避免引用 Result 属性并确保重新收集 myViewModel 对象,但我想知道是否有办法避免创建新列表。
最佳答案
您还没有发布 MyViewModel
的实现但是List<MyType>
从 View 模型返回不会阻止 View 模型被垃圾收集。您可以使用 WeakReference
自行确认这一点:
private void Test(object sender, RoutedEventArgs e)
{
Window myView = new Window();
MyViewModel myViewModel = new MyViewModel();
myView.DataContext = myViewModel;
myView.ShowDialog();
List<MyType> result = myViewModel.Result;
WeakReference viewModelWeakReference = new WeakReference(myViewModel);
myView.DataContext = null;
myViewModel = null;
GC.Collect();
GC.WaitForPendingFinalizers();
bool isViewModelAlive = viewModelWeakReference.IsAlive; //=false
}
...
public class MyViewModel
{
public List<MyType> Result { get; } = new List<MyType>() { new MyType(), new MyType() };
}
isViewModelAlive
是false
和 result.Count
是2
运行上面的示例代码时,即 View 模型已被收集但是 List<MyType>
留在内存中。
请注意 WeakReference.IsAlive
将返回 true
当您持有对执行 GC 测试的方法的强引用时:
List<MyType> _result;
private void Button_Click(object sender, RoutedEventArgs e)
{
_result = openDialog();
}
private List<MyType> openDialog()
{
Window myView = new Window();
MyViewModel myViewModel = new MyViewModel();
myView.DataContext = myViewModel;
myView.ShowDialog();
List<MyType> result = myViewModel.Result;
WeakReference viewModelWeakReference = new WeakReference(myViewModel);
myView.DataContext = null;
myViewModel = null;
GC.Collect();
GC.WaitForPendingFinalizers();
bool isViewModelAlive = viewModelWeakReference.IsAlive;
return result;
}
但是myViewModel
方法返回后仍然有资格进行垃圾收集,因为它没有 GC 根。
所以不需要再创建一个List<MyType>
在这里。
关于c# - 在这种情况下,垃圾收集器是否回收了该对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50549988/