Как сохранить экземпляр класса живым?

2

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

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 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();
    }
}
  • 0
    Не позволяйте этому выйти из области видимости, таким образом, GC не освобождает это
  • 0
    Подождите, это предупреждение, а не ошибка, верно? Ваша программа компилируется нормально, и я уверен, что она работает как положено.
Теги:
wpf

3 ответа

0

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

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

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

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

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

0

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

-1

Что-то должно содержать ссылку на ваш объект, чтобы сборщик мусора не собирал ваш объект.

Не храните его в неиспользуемом приватном поле. Компилятор может оптимизировать его. Даже если он этого не делает в настоящее время, будущая версия компилятора может сделать это. Или вы можете изменить параметры оптимизации, и вдруг ваш код начнет давать сбой.

Измените свое поле на внутреннее

внутреннее чтение только Foo _foo;

Это сохранит объект от GC (ваша первоначальная цель), избавит от предупреждения Visual Studio и сделает ваш код ориентированным на будущее.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню