Is it possible to avoid using ifs in these cases?

Asked

Viewed 2,573 times

9

I have read many materials on the internet about OOP, the overwhelming majority says to avoid if/else at all costs. For an OOP beginner like myself, many doubts arise.

For example:

        if (comboBoxUF.SelectedItem == null)
        {
            return;
        }

How not to use ifs in these cases?

Or in these:

        if (ctrl is ToolStripMenuItem)
        {
                GetMenuItems((ToolStripMenuItem)ctrl , items);
        }

It would be really possible not to use procedural programming when developing a C application#?

  • 1
  • 3

    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.

  • 1

    @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.

3 answers

11


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 ifs, 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:

  • bigown, thank you so much for the reply. Excellent explanation.

  • @Robss70 I’m still going to improve some things, but basically this is it.

3

At all costs no. I would say that in several situations they are avoidable yes. The idea is to establish a programming discipline that does not complicate your code unnecessarily.

I’ll show you some cases where the use of if can be avoided.

1. When the stream returns something

From your example (slightly modified):

    if (comboBoxUF.SelectedItem == null)
    {
        return "É nulo";
    }

    return "Não é nulo";

Notice that if I wrote the else, wouldn’t make the slightest difference. The result would be the same. There is another error that the C# compiler can get called:

Not all code paths Return a value.

It is more common in situations where the code contains if and else, and the method or function needs to return a value.

2. When the test involves a finite relation of values

This is the famous test case as the below:

int valor = new Random().Next(1, 5);
if (valor == 1) { ... }
else if (valor == 2) { ... }
// E assim por diante

A switch is best structured in this case:

int valor = new Random().Next(1, 5);
switch (valor)
{
    case 1: 
        // Faz alguma coisa
        break;
    case 2:
        // Faz outra coisa
        break;
    default: // Neste contexto, seria como um else
        // Faz mais outra coisa
        break;
}

Cases where he has no way of being avoided

Basically, anything that requires flow deviation. You put a very good one: inheritance test.

    if (ctrl is ToolStripMenuItem)
    {
        GetMenuItems((ToolStripMenuItem)ctrl, items);
    }

Recursions are also good examples:

public static int Fibonacci(int numero)
{
    if (numero == 0) return 0;
    if (numero == 1) return 1;
    return Fibonacci(numero - 2) + Fibonacci(numero - 1);
}
  • Gypsy, in the case of a class that validates controls of a form o if would be the most viable ?

  • It depends on what you need to do. If it’s an inheritance check, I believe so.

  • In this case it would be validation if the control is empty, or if it contains a valid value.

  • So yes. I don’t know how it could be done otherwise.

0

What this "overwhelming majority" meant is that it’s better to do so:

It’s better to do it like this: player_x += Sign(player_direcao); //Caso a direção seja 10 retorna 1, caso seja -20 retorna -1 e caso seja 0 retorna 0.

Than so:

if(player_direcao > 0)
{
player_x ++;
}
else if(player_direcao < 0)
{
player_x --;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.