Is it a good practice to have a list containing objects of derived types and then filtering it by type checking when need to call methods specific for one of the types? From what I read typechecking is some kind of code smell and it indicates that OOP isn't fully used.
It indicates that polymorphism isn't fully used. Polymorphism is a big part of OOP.
Now sure, sometimes you're stuck and you can't do it the way you'd like but please understand how to use it to solve this problem when you can.
If for some reason you simply can't change these derived types you can still make that type specific checking move away from you.
static void Main() { List<VagueType> objects = new List<VagueType>() { new VagueType( new DerivedTypeA() ), new VagueType( new DerivedTypeA() ), new VagueType( new DerivedTypeB() ), new VagueType( new DerivedTypeB() ) } //Call common method on all objects in a list foreach(var obj in objects) { obj.CommonMethod(); } //Call something, if needed foreach(var obj in objects) { obj.SomeSpecificMethod(); } } public class VaugeType { public override void CommonMethod() { derived.CommonMethod(); } //Call only specific method for DerivedTypeA objects public void SomeSpecificMethod() { if(derived is DerivedTypeA derivedAObj) //type checking needed { derivedAObj.TypeASpecificMethod(); } } } So wait. Didn't I just use type checking? Yes I did. But I shoved it away from the external interfaceusing algorithm so we can stop looking at the ugly thing every time we use it.
It's not that type checking is evil. It's a code smell that encourages you to stop and think about your design and the problems it's causing. This runs counter to the instincts of new programmers who andtend to pull every ugly detail towards them. Experienced programmers like to shove details away and hide them behind things so we can think about more important things.