I was reading the Github repository about the Clean Code concepts applied to C#, and I was surprised that the pattern matching strategy was recommended for to avoid type checking (in addition https://github.com/thangchung/clean-code-dotnet#avoid-type-checking-part-1
I can understand when you don't really have the control over types defined in a third party, but other than that I think it might be definitely better to define an interface to process some actions.
The example used in that repository is:
// Bad: btw this example cannot even work, the methods are not defined in Object. Going to fork and PR.
public Path TravelToTexas(object vehicle)
{
if (vehicle.GetType() == typeof(Bicycle))
{
vehicle.PeddleTo(new Location("texas"));
}
else if (vehicle.GetType() == typeof(Car))
{
vehicle.DriveTo(new Location("texas"));
}
}
// Good: parent class / interface
public Path TravelToTexas(Traveler vehicle)
{
vehicle.TravelTo(new Location("texas"));
}
or
// Good: pattern matching
public Path TravelToTexas(object vehicle)
{
if (vehicle is Bicycle bicycle)
{
bicycle.PeddleTo(new Location("texas"));
}
else if (vehicle is Car car)
{
car.DriveTo(new Location("texas"));
}
}
Except that pattern matching switch
/ is
translates into something equivalent to if
/ else if
/ else
using the is
operator (translated itself obj as TargetType != null
) + some conditions (and the fact that you don't have to declare some variables upfront).
My question is there any optimization that I am not aware of when using the pattern matching switch
/ is
cause otherwise I don't really see the point of recommending this strategy...?
And the extract take from: https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching#when-clauses-in-case-expressions
To illustrate these new idioms, let's work with structures that represent geometric shapes using pattern matching statements. You are probably familiar with building class hierarchies and creating virtual methods and overridden methods to customize object behavior based on the runtime type of the object.
Those techniques aren't possible for data that isn't structured in a class hierarchy. When data and methods are separate, you need other tools. The new pattern matching constructs enable cleaner syntax to examine data and manipulate control flow based on any condition of that data. You already write if statements and switch that test a variable's value. You write is statements that test a variable's type. Pattern matching adds new capabilities to those statements.
It's not possible for example to use an Adapter pattern instead and basically wrap the entities of the third party into something on which you can have the control. I mean then except in the deadly case to get an uninformative object
I don't really see the point of doing this.