Question Remove the object invoking a class/method

bondra

Well-known member
Joined
Oct 24, 2020
Messages
77
Programming Experience
Beginner
Don't know if the title of the post describes what I want and trying to achieve.
But I try to explain it below.

In the Toy class there's a LowerQuality method from which I want to remove the current toy for an animal if the quality is 0:
abstract class Toy
    {
        public int Quality { get; set; } = 10;

        public virtual int LowerQuality(int inputQuality)
        {
            int calcQuality = Quality - inputQuality;
            Quality = calcQuality;
            Console.WriteLine(" Play has finished!");
            if (Quality <= 0)
            {
                Quality = 0;
                Console.WriteLine($" Quality of the {Name} has decreased with " + inputQuality + " and is now waste and removed from toys list");
                Petowner.Pets[???].Toys.Remove(this); // 1. How can I tell what index of animal that actually call this method?
                Petowner.Pets[0].Toys.Remove(this); // 2. This will work since the animal is specified by a fixed index which needs to be dynamic however
            }
            else
            {
                Console.WriteLine($" Quality of the {Name} has decreased with " + inputQuality + " and is now " + Quality);
            }
            return Quality;
        }
    }

The object that's calling the method LowerQuality() in the Toy object:
    class Cat : Animal
    {
        public override void Interact(Toy toy)
        {
            if (toy is Bone bone)
                quality = 1;

            else if (toy is Ball ball)
                quality = 4;

            toy.LowerQuality(quality); // In this case the cat calls the LowerQuality() method
   
            // Having the code like this i.e. in the cat object makes it possible to remove the current toy item. But having it like this also forces me to have duplicated code in every animal object...
            //if (qualityCheck == 0)
            //{
            //    Toys.Remove(toy);
            //}
        }
    }
 
Last edited:
It's quality :) Quality can have a score of max 10. Then depending on the animal which is interacting with the toy, quality decreases for the toy with x amount.
 
I think quality is not really the correct word. What @bondra is trying to simulate is that each time the animal plays with a toy, it gets more and more worn out. Eventually when the toy gets completely worn out, wants the toy "destroyed" and effectively taken away from the pet. Maybe call it durability. Maybe call it hit points.

Personally, I think that you are going about it the wrong level. You are breaking the Law of Demeter. As you've discovered, how will a toy remove itself from the list that contains it?

The correct thing to do is to a pass updating the wear on all the toys, and then do another pass through all the toys checking their life points. If the life points is down to zero, then remove the toy from the pets toy list. Since the second pass is iterating over all the toys, then it has the container that contains all the toys. That should have ability to remove things from the container.

Off topic: This code:
C#:
if (toy is Bone bone)
    quality = 1;

else if (toy is Ball ball)
    quality = 4;
is a code smell. Whenever you are inspecting the type of an object to determine what kind of object it is, and then doing different behavior based on the type, it is a hint that you should be using polymorphism.
 
It's really frustrating when it comes to polymorphism. I've watched videos och read about it during the day and still don't get its fully potential. So the example above made in the polymorphism way would be much appreciated!
 
It's really frustrating when it comes to polymorphism. I've watched videos och read about it during the day and still don't get its fully potential. So the example above made in the polymorphism way would be much appreciated!
C#:
class Toy
{
    public virtual int GetDamageByPet() => 0;
}

class Bone : Toy
{
    public override int GetDamageByPet() => 1;
}

class Ball : Toy
{
    public override int GetDamageByPet() => 4;
}
 
Oki, what does it look like when a pet call each toy? Say that a cat damage the Ball with 2 while a dog damage it with 4?
 
Ah. That makes things more interesting. I suspect a bunch of people will jump in with different approaches. I recommend starting a different thread regarding this topic about assigning damage to a toy, and then keep this current thread about how to remove the toy once the toy is "destroyed".
 
Back
Top Bottom