Myths
You’re learning that the overwhelming majority of the things you read around don’t make sense. At least not without a good explanation that makes sense.
If they said something is good or bad and they didn’t say why, they’re probably inventing or passing on something they saw somewhere, they didn’t understand and gave their version, creating a "cordless phone". Imagine that it gets worse.
If you see something like this, it’s good to ask questions in good places, where the answers can be evaluated by other people. One of these places is right here. Questioning is what you learn.
The first problem is people selling OOP as a solution to everything, as if it were a maximum paradigm that should always be followed, and worse, that should follow it purely, even in languages that are not purely object-oriented. It is good to do OOP which makes sense. A common myth, too, is to sell certain languages as object-oriented in their essence. No language mainstream has as main paradigm the orientation to object, but several do this marketing (escape of marketing, not necessarily of the language). In fact it is questionable whether there is any pure OO language.
This is important because the question is about using OOP to avoid the if
. There is the tag, cites the paradigm as the basic reference of the problem and asks to compare with another paradigm.
if
can be bad
In fact maintenance may suffer if abuse of the use of ifs
(has great answers about the real problem, I will not repeat here). There are some ways to avoid them that make software maintenance easier, especially when we’re talking about business rules that can be changeable, that are part of a public API. The main form is through polymorphism.
When we are talking about implementation detail there changes figure. It does not yet mean that we should abuse ifs
. But neither can we abuse other mechanisms when the if
is well suited.
Note that they say to avoid the whole mechanism of if
replacing with OOP. There is no point in replacing the if
by a mechanism that does the same thing, such as the switch
or Pattern matching (available in C# 7), for example. The idea they are "selling" is that you have none deviation from the execution flow, where it is characteristic of imperative languages, except functions.
This is also preached by functional languages, which makes more sense.
How to eliminate the if
in the examples cited
Sure I didn’t see their context, but in C#, I don’t know how to make the codes presented without using the if
, not only because they use things that have been developed with a clear intention of being used in if
s, but also because I don’t see what could be better without using them.
Maybe seeing the full context of where these codes are, there these ifs
specific may not be necessary or at least they could be modified, although I find it unlikely that you can do anything much better.
A good indication how difficult it is to do this is in the response of the Gypsy. He tried to give two examples without the if
and failed. One of them the if
continues there and the other just replaced by a switch
which is even more criticized than the if
in itself by the advocates of OOP, since it is even more used to replace polymorphism than the if
.
First example
You have to make a decision depending on whether the value is null. It has how to make some different constructions that can be made, but all would use one if
or something like that.
The only way to avoid it is to ensure that the object would never be null, then it is obvious that the if
would not be necessary. Can you guarantee in this case? I do not think.
In C# 8 you can ensure that an object is not null. Still it will be optional and it is possible that this case makes sense it can have value null
.
In C# 7 you can use Pattern matching to establish nullity and paragraph 9 to establish nullity.
Making a decision there can be a business rule. It is not easy to eliminate this possibility.
Second example
It even indicates that it is possible to delete the if
ensuring that this code only runs within a ToolStripMenuItem
. A technique of specialization could be applied. Then there would be a method that would only accept this type, so it would only be called with such an object. Then the verification and the cast would not be necessary. Obviously another more general method would be needed to execute when the object is a different control.
That one if
exists for pragmatism. If almost all the code is equal between the controls, it is harnessed and only makes a deviation in the specific case. Whether it’s the best or not, depends on seeing the big picture, I can only say it looks better.
Often to use this technique, reuse is avoided and even duplicate code is generated that can hurt maintenance in a worse way. Then one can commit a bigger sin. To fulfill a silly rule one can prefer a whole complicated code.
It would be something like that (without context becomes difficult):
public string GetControlXXX(ToolStripMenuItem ctrl) { //talvez poderia até ter outro nome
...
GetMenuItems(ctrl , items);
...
return ...;
}
public string GetControlXXX(Control ctrl) {
...
//faz alguma coisa com ctrl, mas não precisa ver se é um ToolStripMenuItem
...
return ...;
}
Obviously the problem would need to make sense to have these two methods, I’m not saying the case does, it’s likely until in this particular example does not even do.
Another hypothetical way is if the architecture of your framework work differently. What could avoid the if
, but would create other difficulties in the code.
Other language
If it were any other language it would be different, even then it can’t be a miracle, it doesn’t mean that the code would always be better.
Languages where the function call resolution can be given by the argument value can be deleted ifs
. But that doesn’t mean it’s a good thing. As the resolution will be done at runtime, even where you wouldn’t need it, the performance will pay.
And yet there is another problem already mentioned above: either it would have repeats of code, or the code would have so many indirect that it would be difficult to understand it.
Paradigms
Purely object-oriented languages have if
, even if in a more disguised way.
It is possible to use procedural or non-procedural programming in C#, but I think this has nothing to do with the problem and was only mistakenly posed in the question. In essence it is not possible to program in C# without using the paradigm imperative. Technically it is even possible, but it is impossible to try it, even because OOP is a secondary paradigm.
Completion
Avoid if
to all costs is pretty strong, right? Let’s save a person’s life at all costs? Even if it means killing 200?
The right thing is to do what is easy to read, understand, maintain (even this is the right time to question). And no single, fixed rule can give a definitive answer. A set of correctly applied techniques to the right extent in each case helps to achieve that goal.
Silly rules:
Related >> Why in some if’s situations are considered bad?
– rray
simple if Else has no problem no problem starts when you put many nested and ends up giving a complexity at the time of understanding the code.
– Eduardo Sampaio
@Eduardosampaio although you are correct, the question mentioned in this question is not quite this, it is a comparison with the OOP way of doing things where polymorphism is preferred to flow deviation.
– Maniero