Using Case/Switch and GetType to determine the object
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When you need to branch on the runtime type of an object in C#, you have two common tools: pattern matching in switch or if expressions, and GetType(). They are not interchangeable. Pattern matching answers "is this object compatible with this type", while GetType() answers "what is the exact runtime type of this instance".
Prefer Pattern Matching for Normal Type Dispatch
Modern C# makes type-based branching easiest with pattern matching.
This style is usually better than manual GetType() checks because it gives you a correctly typed variable immediately and works naturally with inheritance.
GetType() Checks Exact Runtime Type
GetType() is useful when you really need an exact type comparison.
That comparison is strict. It does not mean "is assignable to string-like interface". It means the runtime type is exactly System.String.
This distinction matters for inheritance:
If your intent is polymorphic behavior, is or pattern matching is usually the right tool. If your intent is exact type identity, GetType() is appropriate.
Classic switch on the Type Object
If you want to inspect the type object explicitly, you can switch on GetType() as well:
This works, but it is usually less robust than pattern matching. Switching on type names introduces string comparisons and weakens compile-time help.
Use Polymorphism When the Behavior Belongs to the Object
Sometimes the best answer is not runtime type inspection at all. If each type knows how it should behave, virtual methods or interfaces are cleaner than a large switch.
In that design, consumers do not need switch or GetType() at all. They call Area() and let polymorphism handle the rest.
Common Pitfalls
The biggest mistake is calling GetType() on a possibly null reference. That throws immediately, while pattern matching can handle null safely in the same expression.
Another issue is using exact type comparison when inheritance should count as a match. GetType() == typeof(BaseType) fails for derived objects even when they are perfectly valid base-type instances.
People also sometimes build huge type switches where polymorphism or interfaces would be simpler and more maintainable. Runtime type checks are useful, but they are often a sign that behavior is living in the wrong place.
Finally, avoid switching on type names as strings unless you truly need display-oriented logic. It is more fragile than pattern matching and easier to break during refactoring.
Summary
- Use pattern matching when you want normal runtime type dispatch in C#.
- Use
GetType()when you need an exact runtime type comparison. - Remember that
GetType()does not treat derived types as matches for the base type. - Be careful with null when calling
GetType(). - If the behavior belongs to the type itself, polymorphism is often better than any type switch.

