Lets say i have a `zoo` class, with a bunch of collections. The collections are `giraffes`, `elephants`, `tigers` etc. All animal types derive from the same interface or base class, lets call it `IAnimal`.

So in my code i'm running in the same problem in 2 places. I end up in a method, that gets an IAnimal that its supposed to delete, but i dont know which exact type it is. So i basically end up with methods that look like this

    if(animal is Tiger tiger)
       Zoo.Tigers.Remove(tiger);
       TigerRepository.Delete(tiger);
    else if(animal is Giraffe giraffe)
       Zoo.Giraffes.Remove(giraffe);
       GiraffeRepository.Delete(giraffe);
    ....

This code moves around, sometimes it lands in the zoo class, sometimes in a DBService class, sometimes in a viewmodel. Sometimes its a dictionary, but lets be honest its the same thing.

I know i can probably brute force a solution that i never need to touch again with some smart reflection somehow, but that feels like its not really OOP.

I can split up the method it ends up in from a single method that gets an `IAnimal` into several method that get a `Tiger`, `Giraffe` etc, but that feels the same as a big factory method. It feels like i should be able to do something with generics, but it just doesn't work since i don't know the type at compile time. 

The best i can do is a bunch of `DeleteTiger(Tiger tiger)` methods that internally call a  `DeleteAnimal<Tiger>` method that saves a single line of code in each of the delete methods.

This isn't just a theoretical best practice thing, i keep having to go back and back to that method every time i add a new subentity to my application. 

What can i do to stop having to do this? Can i even do anything?

Edit: I don't like the just make an animal collection approach, but it would definitely work with in memory objects. I would never get the idea to model a zoo as "300 animals", its 20 monkeys, 5 tigers... etc.

However how would this approach work with the repositories or entity frameworks dbsets WITHOUT having a method that just switches on the type again takes that repository / dbset and calls the Delete method?

I just saw that EF Cores DBContext actually has just simple Remove(object entity) method, but internally it probably just type checks too. I feel like i cant get around it with a repository pattern approach.