c# - 如何使类实例保持事件状态?

标签 c# wpf

我已经将一个特性封装在一个类中以供窗口使用(我们称这个类为 Foo)。 Foo 在窗口构造函数中实例化,但在那之后,它只需要存在直到窗口结束。问题是 Visual Studio 告诉我可以删除分配给 Foo 实例的私有(private)成员,因为它永远不会被读取(我不在窗口中的任何其他地方使用 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();
    }
}

最佳答案

您不需要将您的 Foo 实例存储在任何变量中。它将由窗口保持事件状态,因为它在此处附加到窗口上的事件:

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

由于这些事件注册,window 将引用 this(Foo 的实例),因此垃圾收集器不会销毁它。 Foo 将保持事件状态,直到窗口实例被销毁,此时 Foo 将不再具有引用并被清除。

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

附言关于变量从未被读取的警告是表明你有一个你不需要的变量。它不以任何方式指示垃圾收集器将做什么。

关于c# - 如何使类实例保持事件状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55767038/

相关文章:

c# - 在 C# 中优雅地处理 XML 文件中的验证错误

C# 限制列表框项目

wpf - 用于内容/内容模板的可重用容器的控件?

c# - View Model Locator 的用途是什么?

Wpf DataGridComboBoxColumn 绑定(bind)在选择数据网格中的另一行后发生

c# - C# 循环问题中的刽子手

c# - 如何在 ASP.net C# 中将 HTML 文本编辑器内容存储和检索到 SQL Server DB

c# - 通过单击按钮在 Windows 窗体中打开 .pdf 文件

WPF 启动按钮位于工具栏选项卡旁边但不在内部

c# - 通过句柄托管 Win32、WinForms 或 WPF 窗口?