Is there any way to decrease the amount of Else and if?

Asked

Viewed 1,797 times

5

I should create the conditions for enrolling students based on their age, I was wondering if there is any way to decrease the amount of if in that part of the code:

int idade = Convert.ToInt32(txtAnoUltimoAniversario.Text) - Convert.ToInt32(txtAnoNascimento.Text);
            if (idade > 17)
            {
                lblCategoria.Text = "Adulto";
            }
            else if (idade < 13)
            {
                lblCategoria.Text = "Juvenil B";
            }
            else if (idade < 10)
            {
                lblCategoria.Text = "Juvenil A";
            }
            else if (idade < 7)
            {
                lblCategoria.Text = "Infantil B";
            }
            else if (idade <= 5)
            {
                lblCategoria.Text = "Infatil A";
            }
            else
            {
                lblCategoria.Text = "Não existe categoria";
            }



        }
  • Ever thought of using switch/case?

  • 2

    No mistake there? Because there are ages in the middle that are without category. First you need to have the correct logic, because this can change optimizations.

  • has error also in logic, if the age is 5 enters the if of < 13

  • Dear Philip, it has nothing to do with the subject, but the order of ifs is certainly wrong, any value less than 13, even if age is 1, will always fall into else if (idade < 13), can do the test sitting the value manually, will always be Juvenil B, even if you put 5 years. See your IF online test: https://ideone.com/cMZgoO

  • it’s true, the logic is all messed up, now that I stopped to look, I’ll try to fix it first.

  • 4

    Even if you can decrease the amount of ifs, what would be the benefit? Probably most of the "solutions" will get worse technically.

  • 3

    Dear Filipe, I totally agree with @Bacco, I mean, if you really had 20 ifit would even be reasonable to try a Dictionary (or an enumerator), because it would really have a problem (since 20 is an exaggeration), but it would certainly have a form one or more forms specific to solve (that will depend of each code, NAY has magic global solution), but shortening Ifs of nothing will help here, Alii will decrease until ease of reading, what should worry. Some people think of lowering ifs and creating megazord classes, which is even worse.

  • @Filipe. C Did any of the answers solve your question? Do you think you can accept one of them? See [tour] how to do this, if you haven’t already done so. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site

  • @Filipe. C With C# 9.0, you can reduce ifs with the new switch statement format. https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/operators/switch-expression

Show 4 more comments

2 answers

10

Even before version 8 in essence it does not (see below it looks much better in newer versions), at least not in a worthwhile way. It is possible to shorten the code and it is possible to fix a problem when the data is typed wrong that is not contemplated there. I also think there’s a logic problem in this whole comparison, but you can’t say.

if (!int.TryParse(txtAnoUltimoAniversario.Text, out var aniversario) || !int.TryParse(txtAnoNascimento.Text, out var ano) {
    //faz alguma coisa aqui para indicar que os dados foram digitados errados
    //Pode ser que seja dizer que não tem categoria, precisa pensar na UX
}
var idade = aniversario - ano;
if (idade < 6) lblCategoria.Text = "Infatil A";
else if (idade < 7) lblCategoria.Text = "Infantil B";
else if (idade < 10) lblCategoria.Text = "Juvenil A";
else if (idade < 13) lblCategoria.Text = "Juvenil B";
else if (idade > 17) lblCategoria.Text = "Adulto"; //e os que estão entre 13 e 17 não existem?
else lblCategoria.Text = "Não existe categoria";

I thought about using a dictionary, but I wouldn’t hurt the performance to do something that would have a larger number of lines than the direct solution. If it had greatly reduced the number of lines maybe I would, but not in this case, including because there may be exceptions in the future that the dictionary does not even work.

What you can do is shorten the code a little more by putting a short name variable with the strings and then attribute it to label.

I made a slightly different code to test:

using static System.Console;

public class Program {
    public static void Main() {
        Compara(20, 15);
        Compara(20, 14);
        Compara(20, 11);
        Compara(20, 8);
        Compara(20, 2);
    }
    private static void Compara(int aniversario, int ano) {
        var idade = aniversario - ano;
        string texto;
        if (idade < 6) texto = "Infatil A";
        else if (idade < 7) texto = "Infantil B";
        else if (idade < 10) texto = "Juvenil A";
        else if (idade < 13) texto = "Juvenil B";
        else if (idade > 17) texto = "Adulto"; //e os que estão entre 13 e 17 não existem?
        else texto = "Não existe categoria";
        WriteLine(texto);
    }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

A switch would leave even bigger, but in C# 8 has a syntax that can be useful to use the switch, with 9 even better:

using static System.Console;

public class Program {
    public static void Main() {
        Compara(20, 15);
        Compara(20, 14);
        Compara(20, 11);
        Compara(20, 8);
        Compara(20, 2);
    }
    private static void Compara(int aniversario, int ano) => WriteLine((aniversario - ano) switch {
            < 6 => "Infatil A",
            < 7 => "Infantil B",
            < 10 => "Juvenil A",
            < 13 => "Juvenil B",
            > 17 => "Adulto",
            _ =>  "Não existe categoria",
        });
}

Behold working in the .NET Fiddle. Also put on the Github for future reference.

Shorter and more efficient than dictionary option.

10

Can use a dictionary alternatively:

var idade = 12;

var dic = new Dictionary<int, string>
{
    { 6, "Infatil A" },
    { 7, "Infatil B" },
    { 10, "Juvenil A" },
    { 13, "Juvenil B" },
    { 18, "Não existe categoria" },
    { int.MaxValue, "Adulto" },
};

var result = dic.OrderBy(k => k.Key).FirstOrDefault(e => idade < e.Key).Value;

Browser other questions tagged

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