You are thinking that using reflection and casting at runtime is not a sensible thing because it is not optimal, but you must consider that constraints in existing code bases will often make writing optimal solutions too costly.
An example is:
For some reason or another you've written a thread dispatcher that will dynamically spin up threads and route the outputs of these threads into new threads. (e.g. https://github.com/bilus/pipes )
Obviously this library will need to do run-time casting of types already as C# makes it too difficult to orchestrate these threads without some shared type. (Here is an example of Microsoft following this pattern. https://msdn.microsoft.com/en-us/library/dd321424(v=vs.110).... )
Now you need to hook validation into this existing dispatching library by assosciating validators with the outputs of particular threads. Without a shared type you cannot invoke the validator, but it sure is convenient to write the validator using generics.
Another example is:
You have two interfaces, "ISerializable" and "IEquatable", and two validators, "Validator<ISerizable>" and Validator<IEquatable>", and these validators apply to multiple classes.
To run all of these validators against a given class you have three (un)reasonable choices:
* Create a boilerplate wrapper class for each of these validators for each class that they apply to, and store them against that class somehow. The disadvantage of this is that you lose track of which validators are shared between classes which may be important for some optimisation.
* Create a non-genic type "IValidator" or "Validator" that all validators share and put these in a collection. (i.e. as mentioned by the grandparent of this post).
* Bite the bullet: The code that calls these validators has to be duplicated. (This is the incorrect choice though because some day you may need to add a spin-up/teardown before running the validators and now you don't have a centralized location to do this)
Another example is:
You are writing validators for types from a 3rd party library. You may not modify the source code of this library, because it's WinForms. You've been tasked with a set of arbitrary validation tasks for your multi-million line codebase. Maybe you need to add a spell checker for all user-editable text? Maybe any control that is bound to a particular property needs an orange background.
Suddenly you have a case where you really do need to do casting and reflection to figure out which validators to run, as you perform the unfortunate evil of a recursive search through the entire control tree to hook up your validation, rather than re-writing a few thousand files.