Как сохранить экземпляр класса живым? - PullRequest
2 голосов
/ 19 апреля 2019

Я инкапсулировал объект в классе, который будет использоваться окном (назовем этот класс Foo).Foo создается в конструкторе окна, но после этого ему ничего не нужно, кроме как существовать до конца окна.Проблема заключается в том, что Visual Studio сообщает мне, что закрытый член, назначенный экземпляру Foo, можно удалить, поскольку он никогда не читается (я не использую экземпляр Foo где-либо еще в окне, кроме конструктора).Я предполагаю, что это делает Foo кандидатом на сборку мусора, но, возможно, есть что-то, что сохранит Foo в живых, о чем я не знаю.Эту проблему можно решить, унаследовав ее от Window и реализовав эту функцию и используя ее в качестве базового класса Window, но Foo - не единственная подобная функция, и C # не обрабатывает множественное наследование.Любые комментарии или советы приветствуются.

PS: Это приложение WPF в шаблоне MVVM.

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 голосов
/ 20 апреля 2019

Вам не нужно хранить ваш экземпляр Foo в любой переменной.Оно будет поддерживаться окном, потому что оно присоединяется к событиям в этом окне:

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

Из-за этих регистраций событий window будет иметь ссылку на this (экземпляр Foo) и поэтому сборщик мусора не уничтожит его.Foo будет оставаться в живых до тех пор, пока экземпляр окна не будет уничтожен, после чего Foo больше не будет иметь ссылку и будет очищен.

(Если Foo в какой-то момент решит отменить регистрацию прослушивателей событий, тогда он также будет уничтожен в этом случае.)

PS Предупреждение о том, что переменная никогда не читается, означает, что у вас есть переменная, которая вам не нужна.Это никоим образом не указывает на то, что будет делать сборщик мусора.

0 голосов
/ 19 апреля 2019

Пока существует объект, который содержит ссылку на экземпляр foo, foo не будет собирать мусор. Визуальная студия пытается сказать, что вы можете удалить этот кусок кода, потому что вы его нигде не используете, он связан исключительно с качеством кода, а не с сборкой мусора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...