0

I made my own ObservableCollection with the help from https://learn.microsoft.com/en-us/dotnet/standard/events/observer-design-pattern this link. I can add animals in to a list with my own function .AddAnimal() but how could I remove a specific animal thats in my lists with .remove(). So if I have like the following animals in my list: dog, cat, fish, hamster. how could I get it so it removes: .remove(fish or "fish"). I'm able to remove it out of my private List<Animal> animals; but not out of private List<IObserver<Animal>> observers; this is my code so far, this is my observableInventory(observableCollection) where I have the add/remove() methodes

    namespace C_Advanced.Model
{
    internal class ObservableInventory : IObservable<Animal>
    {
        private List<IObserver<Animal>> observers;
        private List<Animal> animals;

        public ObservableInventory()
        {
            observers = new List<IObserver<Animal>>();
            animals = new List<Animal>();
        }

        public IDisposable Subscribe(IObserver<Animal> observer)
        {
            // Check whether observer is already registered. If not, add it
            if (!observers.Contains(observer))
            {
                observers.Add(observer);
            }
            return new Unsubscriber<Animal>(observers, observer);
        }

        public void AddAnimal(Animal animal)
        {
            animals.Add(animal);
            foreach(IObserver<Animal> observer in observers)
            {
                observer.OnNext(animal);
            }
        }
        public void RemoveAnimal(Animal animal)
        {
            //this part doesn't work
            animals.Remove(animal);
        }
    }
}

this is my inventoryObserver.cs:

    namespace C_Advanced.Model
{
    internal class InventoryObserver : IObserver<Animal>
    {
        public string Name { get; set; }
        public void OnCompleted()
        {
            throw new NotImplementedException();
        }

        public void OnError(Exception error)
        {
            throw new NotImplementedException();
        }

        public void OnNext(Animal value)
        {
            Console.WriteLine("I am {0} and this is the price of the animal: {1}",Name, value.Price);
        }
    }
}

this is my program.cs, here I want to be able to do .remove():

internal class Program
{
    static void Main(string[] args)
    {
        double TotalWeight = 0;

        ObservableInventory inventory = new();
        InventoryObserver observer1 = new() { Name = "Seller1" };
        InventoryObserver observer2 = new() { Name = "Seller2" };
        inventory.Subscribe(observer1);
        inventory.Subscribe(observer2);

        inventory.AddAnimal(new Bird { Price = 10, Weight = 20 });
        inventory.AddAnimal(new Fish { Price = 2 });
        inventory.RemoveAnimal(new Fish { Name = "splash"});
    }
}

and here is my animal.cs:

    namespace C_Advanced.Model
{
    public abstract class Animal
    {
        public double Price { get; set; }
        public double Weight { get; set; }
        public string Name{ get; set; }


        //internal Animal(double AnimalPrice, double AnimalWeight)
        //{
        //    this.Price = AnimalPrice;
        //    this.Weight = AnimalWeight;
        //}

        public virtual void MakeSound()
        {
            Console.WriteLine("SOUND");
        }

        public virtual void MyType()
        {
            Console.WriteLine("ANIMAL TYPE");
        }

        public double Prijs
        {
            get { return this.Price; }
        }

        public double From
        {
            get { return this.Weight; }
        }


    }
}
hasbullah
  • 45
  • 5
  • 1
    But it is working in my test. The item is removed from private List animals; if it is the same instance that was added. What is not removed it is the Observer from List> observers of that animal. – D A Apr 15 '22 at 14:34
  • @DA do u maybe have any idea on how to remove it from IObserver aswell. because u cant do .remove(animal) on that – hasbullah Apr 15 '22 at 14:40
  • What is `inventory.RemoveAnimal()` with no Animal parameter supposed to do? How did that code even compile? – HasaniH Apr 15 '22 at 16:18
  • Same for `animals.Remove()`, shouldn't it be `animals.Remove(animal)`? – HasaniH Apr 15 '22 at 16:20
  • @HasaniH Not, that doesn't work like that, only if i do "inventory.RemoveAnimal(new Fish { Name = "splash"})" but like DA said I need to empty the IObserver list and not the private animal list – hasbullah Apr 15 '22 at 16:22
  • @HasaniH ur correct. I was just testing some things out and it seems like I forgot to put that back. I have updated the code now tho – hasbullah Apr 15 '22 at 16:23

1 Answers1

0

Given your comment about inventory.RemoveAnimal(new Fish { Name = "splash"}) being the issue, I think your problem is with equality checking.

var fish1 = new Fish { Name = "splash"};
ObservableInventory animals = new();
animals.AddAnimal(fish1);
// the line below does not remove fish1 from the collection
animals.RemoveAnimal(new Fish { Name = "splash"});

You have not overidden the Equals method or provided an IEqualityComparer so that Animals with the same Name are considered equal. If that's the behavior you want you'll need to implement it otherwise Remove will use reference equality i.e.

// to remove fish1
animals.RemoveAnimal(fish1);
HasaniH
  • 8,232
  • 6
  • 41
  • 59