I learned F# before C#, so I am unused to inheritance and do not understand its best practices.
As I understand, the nearest equivalent to the discriminated union in OOP (the “one of” data type) is the subclass. The difference is that inheritance (usually) allows new cases to be added arbitrarily while the DU allows behaviors using the existing cases to be added arbitrarily. So the inherited entity defines all behaviors and allows cases (with their implementations) to be added anywhere, whereas the DU defines all cases and allows behaviors to be added anywhere.
Now I am working on a C# project whose previous developers apparently were accustomed to using DUs; I find runtime type matches frequently. My reading on the Internet indicates that runtime type matches are a Bad Thing, which makes sense to me since they inherently lack exhaustive matching. The OOP right way is to use polymorphism instead.
At last, here is my question: If I move all the behavior currently implemented in the runtime matches to the classes being matched, then those classes will grow significantly and will require access to far more of the code than they currently do, besides violating the single-responsibility principle. How do I avoid that? Or is there some refactoring I can perform later to remedy it?