如何保持类实例的生命?

时间:2019-04-19 19:41:38

标签: c# wpf

我已经将一个功能封装在一个窗口要使用的类中(我们称此类为Foo)。在窗口构造函数中实例化了Foo,但是在那之后,直到窗口结束之前,它都不需要存在。问题是Visual Studio告诉我可以删除分配给Foo实例的私有成员,因为它永远不会被读取(我不在窗口中的其他任何地方使用Foo实例,除非在构造函数中)。我想这使Foo成为垃圾收集的候选者,但是也许有一些我不知道的事情可以使Foo存活下来。可以通过派生Window并实现该功能并将其用作基础Window类来解决该问题,但是Foo并不是唯一的类似功能,并且C#无法处理多重继承。欢迎任何意见或建议。

PS:这是MVVM模式中的WPF应用程序。

public partial class MainView : Window
{
    private readonly Foo _foo;

    public MainView()
    {
        InitializeComponent();

        _foo = new Foo(this);
    }

    // Could that be a solution (but it's annoying) ?
    //
    //~MainView()
    //{
    //    GC.KeepAlive(_foo);
    //}
}
public sealed class Foo
{
    public Foo(Window window)
    {
        window.SourceInitialized += OnSourceInitialized;
        window.Closed += OnClosed;
    }

    private void OnSourceInitialized(object sender, EventArgs e)
    {
        LoadSomething();
    }

    private void OnClosed(object sender, EventArgs e)
    {
        SaveSomething();
    }
}

2 个答案:

答案 0 :(得分:0)

只要有一个对象持有对foo实例的引用,就不会对foo进行垃圾收集。 visual studio试图说的是,您可以删除这段代码,因为您没有在任何地方使用它,这纯粹与代码质量有关,而不是垃圾回收。

答案 1 :(得分:0)

您无需将Foo实例存储在任何变量中。它会在窗口中保持活动状态,因为它将自身附加到此处的窗口事件上:

window.SourceInitialized += OnSourceInitialized;
window.Closed += OnClosed;

由于这些事件的注册,window将引用thisFoo的实例),因此垃圾收集器不会销毁它。 Foo将保持活动状态,直到销毁窗口实例为止,此时Foo将不再具有引用并进行清理。

(如果Foo在某个时候决定取消注册那些事件侦听器,那么在这种情况下它也将被销毁。)

P.S。关于永远不会读取的变量的警告是表明您拥有不需要的变量。它丝毫没有表明垃圾收集器会做什么。