Как Удалить Потерянный Экземпляр Из Коллекции?

#c# #unity3d #collections #garbage-collection #instance-variables

Вопрос:

Итак, допустим, у меня есть что-то вроде этого:

 public class Foo : IDisposable {
   
    // Singleton class accessible through FooEventEmitter.Instance
    private sealed class FooEventEmitter : Singleton <FooEventEmitter> {

        public HashSet <Foo> Instances { get; } = new HashSet<Foo>();

        // This method gets called continously.
        public void Update() {

             foreach (var instance in this.Instances) {
                 
                 if (somethingHappensAndEventShouldBeCalled)
                     instance.SomeEvent?.Invoke(); 
             }
        }

    }


    // The event to be emitted.
    public event Action SomeEvent = delegate { };


    public Foo () {

        FooEventEmitter.Instance.Instances.Add(this);
    }


    public void Dispose() {

        FooEventEmitter.Instance.Instances.Remove(this);
    }
}
 

И в другой части кода я делаю это:

 public class Test {

    private Foo foo = null;


    // This method gets called automatically.
    public void Start() {

         this.foo = new Foo();
    } 
    
    public void SetNewValueForFoo() {

        this.foo = new Foo();
    }

}
 

Мой вопрос в основном заключается в том, что происходит с первым значением Foo , которое было зарегистрировано FooEventEmitter при создании? Есть ли какой-либо способ получить к нему доступ и удалить его из коллекции Instances , которая обновляется после потери уникальной ссылки?

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

Вот почему я использую частный «Менеджер экземпляров» (пользователю не нужно знать о его существовании), который может обновляться и оценивать каждый экземпляр, чтобы вызывать события, когда это необходимо.

Дело в том, что если я изменяю значение в переменной foo Test класса, первый экземпляр продолжает оцениваться, когда он мне больше не нужен, потому что я потерял способ доступа к нему. Как я могу после new Foo установки значения удалить первый экземпляр из «Менеджера экземпляров»? Или это вообще невозможно сделать?

Если я должен сделать это по-другому или я делаю что-то не так, может ли кто-нибудь сказать мне?
На случай, если вам будет полезно сказать: я работаю с Unity.

Спасибо!

Правка: Вот одноэлементный класс. Он предназначен для работы с игровыми объектами Unity, и это довольно большая реализация, поэтому я свяжу файл: UnitySingleton.

Кроме того, примите во внимание, что пользователь может не знать, что Foo его следует удалить до обновления его значения. Я пытаюсь найти способ сделать это автоматически для него.

Комментарии:

1. Не могли бы вы также поделиться кодом класса «Синглтон»?

2. @Lyxodius Я могу ошибаться, но есть большая вероятность, что так оно и будет this implementation .

3. Когда вы устанавливаете новое значение Foo, не могли бы вы сначала проверить, существует ли foo, и если да, то вызвать функцию Dispose? if (this.foo != null) this.foo.Dispose();

4. @Lyxodius Я просто отредактировал вопрос и добавил код.

5. @TEEBQNE Я действительно взял эту реализацию в качестве ссылки, вы совсем не ошиблись.

Ответ №1:

Вы правы, это невозможно сделать, если ваш код написан таким образом. Вам нужно сохранить ссылку на файл, который вы хотите удалить.