Precedência no C#

Olá!!!

Essa é simples, mas acho interessante compartilhar… quem desenvolve em C# deve saber, ou pelo menos deveria, que todo tipo deriva de System.Object. Isso acarreta que todo tipo herda os métodos de System.Object, incluindo o famoso ToString().

E daí? E daí que caso você precise concatenar uma string com alguma variável, não importando o tipo, basta apenas concatenar utilizando o operador +, por exemplo:

DateTime nascimento = DateTime.Parse(“26/07/1980”);

string nome = “JP”;

int idade = 29;

Console.WriteLine(“Eu me chamo “+nome+” tenho “+idade+ ” pois nasci em ” +nascimento);

Até aí nada de muito interessante, entretanto vamos supor o seguinte caso:

int i = 10;

Console.WriteLine(“Qual o valor de ” + i + 5 + ” ?”);

Nesse caso será impresso na tela “Qual o valor de 105 ?”. Isto porque devido a precedência, o valor de i e de 5 são convertidos para string e só então são concatenados. Para obter o valor da soma de i e 5 basta utilizar parênteses:

Console.WriteLine(“Qual o valor de ” + (i + 5) + ” ?”);

Ou ainda o método Format da classe String:

Console.WriteLine(string.Format(“Qual o valor de {0} ?”, i + 5));

É isso aí! Para alguns pode ser algo trivial, mas para quem está começando espero que tenha utilidade.

Abraços e até a próxima!

Removendo itens de uma List<>

Olá,

estava dando uma vasculhada em uns emails antigos e achei uma mensagem que havia enviado para uma lista de discussão de dot.net sobre como remover itens de uma coleção do tipo List<T>.

Se tentarmos remover um item de uma lista enquanto estivermos iterando sobre a mesma utilizando o foreach, uma exceção será lançada, por exemplo:

private List<string> lista;

lista = new List<string>();

lista.Add(“a”);

lista.Add(“b”);

lista.Add(“c”);

foreach (string s in lista)

lista.Remove(s);

O código acima lançará uma exceção pois estamos removendo um item da coleção enquanto estamos iterando sobre a mesma.

Uma alternativa é utilizar o código abaixo que utiliza o método ForEach da classe List<> e o conceito de delegates. Podemos pensar num delegate como sendo um ponteiro de função:

private List<string> lista;

lista = new List<string>();

lista.Add(“a”);

lista.Add(“b”);

lista.Add(“c”);

lista.ForEach(Action);

}

private void Action(string s)

{

if (s.Equals(“a”))

lista.Remove(s);

}

É possível utilizar ainda um delegate anônimo, aonde não precisaríamos definir o método Action e o código do mesmo seria inserido inline, mas acho que essa solução prejudica a legibilidade, vejamos:

lista.ForEach(delegate(string s) { if (s.Equals(“a”)) ls.Remove(s); });

Vale a pena lembrar que ainda existem, pelo menos, duas formas de se conseguir o mesmo objetivo. Uma utilizando goto, que é altamente condenado, mas que nesse caso não vejo tantos problemas:

laco:

for (int i = 0; i < lista.Count; i++)

{

string s = lista[i];

if (s.Equals(“a”))

{

lista.Remove(s);

goto laco;

}

}

e outra é utilizando for:

for (int i = 0; i < lista.Count; i++)

{

string s = lista[i];

if (s.Equals(“a”))

{

lista.Remove(s);

i–;

}

}

É isso aí. Só quis mais uma vez compartilhar conhecimento. Gostaria de saber de alguém de Java se essas alternativas também se aplicam nessa linguagem.

Abraços e até a próxima!

Switch vs. Delegate

Olá novamente!

Hoje recebi um email de um colega, através de uma lista de discussão de dot.net, com uma dúvida sobre a otimização de switchs. Lembrei então de já ter visto um código em C que utilizava ponteiros de funções ao invés de switchs.

Resolvi então implementar uma solução similar em C# utilizando delegates no lugar dos ponteiros de funções. O código implementa as quatro operações aritméticas básicas dados dois números reais.

Para isso, foi definida a classe Calculadora com os métodos referentes as quatro operações. Além desses métodos foram definidos outros dois, o ExecutaComSwitch, que e executa uma operação realizando um teste com switch e o ExecutaComDelegate, que recebe um delegate com a operação a ser executada.

O programa principal recebe os valores de duas variáveis reais e em seguida executa as quatro operações utilizando o método com switch e o método com delegate.

O código da aplicação (console) é o seguinte:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Switch
{
public enum TipoOperacao { Soma, Subtracao, Multiplicacao, Divisao};
public delegate double OperacaoDelegate(double a, double b);
public class Calculadora
{
public double Soma(double a, double b)
{
return a + b;
}
public double Substracao(double a, double b)
{
return a – b;
}
public double Multiplicacao(double a, double b)
{
return a * b;
}
public double Divisao(double a, double b)
{
return a / b;
}
public double ExecutaComSwitch(TipoOperacao op, double a, double b)
{
double resultado = 0;
switch (op)
{
case TipoOperacao.Soma:
resultado = this.Soma(a, b);
break;
case TipoOperacao.Subtracao:
resultado = this.Substracao(a, b);
break;
case TipoOperacao.Multiplicacao:
resultado = this.Multiplicacao(a, b);
break;
case TipoOperacao.Divisao:
resultado = this.Divisao(a, b);
break;
}
return resultado;
}
public double ExecutaComDelegate(OperacaoDelegate op, double a, double b)
{
return op(a, b);
}
}
class Program
{
static void Main(string[] args)
{
double a, b;
Calculadora calc = new Calculadora();
Console.Clear();
Console.WriteLine(“Informe o valor de A:”);
double.TryParse(Console.ReadLine(), out a);
Console.WriteLine(“Informe o valor de B:”);
double.TryParse(Console.ReadLine(), out b);
Console.WriteLine();
Console.WriteLine(“Usando switch:”);
double soma = calc.ExecutaComSwitch(TipoOperacao.Soma, a, b);
Console.WriteLine(“Soma: {0}”, soma.ToString(“#,##0.00”));
double subtracao = calc.ExecutaComSwitch(TipoOperacao.Subtracao, a, b);
Console.WriteLine(“Subtração: {0}”, subtracao.ToString(“#,##0.00”));
double multiplicacao = calc.ExecutaComSwitch(TipoOperacao.Multiplicacao, a, b);
Console.WriteLine(“Multiplicação: {0}”, multiplicacao.ToString(“#,##0.00”));
double divisao = calc.ExecutaComSwitch(TipoOperacao.Divisao, a, b);
Console.WriteLine(“Divisão: {0}”, divisao.ToString(“#,##0.00”));
Console.WriteLine();
Console.WriteLine(“Usando delegate:”);
soma = calc.ExecutaComDelegate(calc.Soma, a, b);
Console.WriteLine(“Soma: {0}”, soma.ToString(“#,##0.00”));
soma = calc.ExecutaComDelegate(calc.Substracao, a, b);
Console.WriteLine(“Subtração: {0}”, subtracao.ToString(“#,##0.00”));
soma = calc.ExecutaComDelegate(calc.Multiplicacao, a, b);
Console.WriteLine(“Multiplicação: {0}”, multiplicacao.ToString(“#,##0.00”));
soma = calc.ExecutaComDelegate(calc.Divisao, a, b);
Console.WriteLine(“Divisão: {0}”, divisao.ToString(“#,##0.00”));
Console.ReadLine();
}
}
}

using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace Switch{    public enum TipoOperacao { Soma, Subtracao, Multiplicacao, Divisao};
public delegate double OperacaoDelegate(double a, double b);
public class Calculadora    {        public double Soma(double a, double b)        {            return a + b;        }
public double Substracao(double a, double b)        {            return a – b;        }
public double Multiplicacao(double a, double b)        {            return a * b;        }
public double Divisao(double a, double b)        {            return a / b;        }
public double ExecutaComSwitch(TipoOperacao op, double a, double b)        {            double resultado = 0;            switch (op)            {                case TipoOperacao.Soma:                    resultado = this.Soma(a, b);                    break;                case TipoOperacao.Subtracao:                    resultado = this.Substracao(a, b);                    break;                case TipoOperacao.Multiplicacao:                    resultado = this.Multiplicacao(a, b);                    break;                case TipoOperacao.Divisao:                    resultado = this.Divisao(a, b);                    break;            }            return resultado;        }
public double ExecutaComDelegate(OperacaoDelegate op, double a, double b)        {            return op(a, b);        }    }
class Program    {        static void Main(string[] args)        {            double a, b;            Calculadora calc = new Calculadora();                       Console.Clear();            Console.WriteLine(“Informe o valor de A:”);            double.TryParse(Console.ReadLine(), out a);            Console.WriteLine(“Informe o valor de B:”);            double.TryParse(Console.ReadLine(), out b);            Console.WriteLine();
Console.WriteLine(“Usando switch:”);            double soma = calc.ExecutaComSwitch(TipoOperacao.Soma, a, b);            Console.WriteLine(“Soma: {0}”, soma.ToString(“#,##0.00”));            double subtracao = calc.ExecutaComSwitch(TipoOperacao.Subtracao, a, b);            Console.WriteLine(“Subtração: {0}”, subtracao.ToString(“#,##0.00”));            double multiplicacao = calc.ExecutaComSwitch(TipoOperacao.Multiplicacao, a, b);            Console.WriteLine(“Multiplicação: {0}”, multiplicacao.ToString(“#,##0.00”));            double divisao = calc.ExecutaComSwitch(TipoOperacao.Divisao, a, b);            Console.WriteLine(“Divisão: {0}”, divisao.ToString(“#,##0.00”));            Console.WriteLine();
Console.WriteLine(“Usando delegate:”);            soma = calc.ExecutaComDelegate(calc.Soma, a, b);            Console.WriteLine(“Soma: {0}”, soma.ToString(“#,##0.00”));            soma = calc.ExecutaComDelegate(calc.Substracao, a, b);            Console.WriteLine(“Subtração: {0}”, subtracao.ToString(“#,##0.00”));            soma = calc.ExecutaComDelegate(calc.Multiplicacao, a, b);            Console.WriteLine(“Multiplicação: {0}”, multiplicacao.ToString(“#,##0.00”));            soma = calc.ExecutaComDelegate(calc.Divisao, a, b);            Console.WriteLine(“Divisão: {0}”, divisao.ToString(“#,##0.00”));

Console.ReadLine();        }    }}