J
Indeed the command switch-case it is enough ugly and almost always indispensable.Instead of using this command or long strings if-elseif-elseif..., you can use dictionaries.In your case, you would fill a dictionary of dictionaries, with the following semantics:profissão -> site -> profissão naquele site
So instead of making a long, confusing, ugly, and difficult maintenance imperative code like this:switch (profissao_selecionada)
{
case "Engenheiro(a)":
switch (site_selecionado)
{
case "site A":
profissao_no_outro_site = "Engenheiro/Arquiteto";
break;
case "site B":
profissao_no_outro_site = "Engenheiro (outros)";
break;
}
break;
case "Astronauta":
switch (site_selecionado)
{
case "site A":
profissao_no_outro_site = "Cosmonauta";
break;
case "site B":
profissao_no_outro_site = "Espaçonauta";
break;
}
break;
}
you can associate profession and site in a more declarative way:profissoes["Engenheiro(a)"]["site A"] = "Engenheiro/Arquiteto";
profissoes["Engenheiro(a)"]["site B"] = "Engenheiro (outros)";
profissoes["Astronauta"]["site A"] = "Cosmonauta";
profissoes["Astronauta"]["site B"] = "Espaçonauta";
And then, in only one line, without any switch-case, you check how the profession selected in the combo is defined on a given site, more or less so:profissao_no_outro_site = profissoes[profissao_selecionada][site_selecionado];
See that you can use the dictionary itself to popular professions in the combo rather than replicate them in the combo and code, so give maintenance on items in a single place.Full ExampleIf you have any questions, see this complete functional example:public partial class Form1 : Form
{
Dictionary<String, Dictionary<String, String>> profissoes;
public Form1()
{
InitializeComponent();
var engenheiro = new Dictionary<String, String>();
engenheiro["site A"] = "Engenheiro";
engenheiro["site B"] = "Engenheiro (outros)";
engenheiro["site C"] = "Engenheiro(a)/Arquiteto(a)";
var astronauta = new Dictionary<String, String>();
astronauta["site A"] = "Cosmonauta";
astronauta["site B"] = "Espaçonauta";
astronauta["site C"] = "Lunático";
profissoes = new Dictionary<String, Dictionary<String, String>>();
profissoes["Engenheiro(a)"] = engenheiro;
profissoes["Astronauto(a)"] = astronauta;
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (var profissao in profissoes)
comboProfissoes.Items.Add(profissao.Key);
}
private void seleciona_Click(object sender, EventArgs e)
{
var profissaoSelecionada = (String)comboProfissoes.SelectedItem;
var mensagem = "A profissão " + profissaoSelecionada
+ " no site B é " + profissoes[profissaoSelecionada]["site B"];
MessageBox.Show(mensagem);
}
}
Cujo "output" is like this: Storing complex code in the dictionaryAnd if in each block Home Did you need to run some code lines instead of simply setating a variable like I did in the above example? The dictionary is still the solution!In the above example, we use the dictionary to store the profession legend on another site, but we can use it to store any object and not just strings. That is: we can add code blocks in the dictionary to run at a timely time, dismissing the switch-case in virtually any situation.Since the dictionary supports objects and almost everything in C# is an object, there are several ways to store code blocks in the dictionary: you can store actions, functions, can define your own delegates, interfaces, abstract classes... The sky is the limit:DNote that the dictionary's own key can also be any object, further expating the horizons.A small exampleLet's assume that same blocon switch from above do more things besides simply sealing a variable:switch (profissao_selecionada)
{
case "Engenheiro(a)":
switch (site_selecionado)
{
case "site A":
// faz um trabalho muito específico aqui
break;
case "site B":
// faz outro trabalho específico aqui
break;
}
break;
case "Astronauta":
switch (site_selecionado)
{
case "site A":
// mais trabalhos complexos
break;
case "site B":
// outros serviços impensáveis
break;
}
break;
}
What you have to do is encapsulate each block of code in methods with a common signature:void Metodo_01()
{
// faz um trabalho muito específico aqui
}
void Metodo_02()
{
// faz outro trabalho específico aqui
}
void Metodo_03()
{
// mais trabalhos complexos
}
void Metodo_04()
{
// outros serviços impensáveis
}
Then you declare a delegate with this common signature (or uses the native .Net delegates, if you prefer):delegate void ProcessadorProfissoes();
And then fill the dictionary as before, only now adding methods in it instead of adding strings:var processadorEngenheiro = new Dictionary<String, ProcessadorProfissoes>();
processadorEngenheiro["site A"] = Metodo_01;
processadorEngenheiro["site B"] = Metodo_02;
var processadorAstronauta = new Dictionary<String, ProcessadorProfissoes>();
processadorAstronauta["site A"] = Metodo_03;
processadorAstronauta["site B"] = Metodo_04;
processadorProfissoes = new Dictionary<string,Dictionary<string, ProcessadorProfissoes>>();
processadorProfissoes["Engenheiro(a)"] = processadorEngenheiro;
processadorProfissoes["Astronauta"] = processadorAstronauta;
Now, to run the code block referring to the profession and site selected, just this simple line without switch-case, without if you don't know...processadorProfissoes[profissaoSelecionada]siteSelecionado;
ConclusionCode with blocks switch-case and long blocks if-else if most of the time can be better expressed through dictionaries or combination of dictionaries, simplifying code maintenance.In the examples of this response, strings and methods with simple signature were stored in the dictionary; but we can store any type of object, and then have methods with complex signatures, returning values, or complete objects filled with state to be able to perform complex works.