quarta-feira, 6 de fevereiro de 2008

[Off-Topic] Português correto

Eu sei que português e gramática eram matérias chatas na escola (pelo menos eu achava..rs), e que ficar estudando todas aquelas regras de ortografia era chato pra caramba, mas escrever corretamente é fundamental.

Sim, esse blog é de programação, mas resolvi escrever sobre isso pois, de vez em quando, nos fóruns e grupos de discussão que participo vejo mensagens como essa :

"Pessoal meu projeto sumiu tudo que tinha nele de visual ficando com essatela em todos mas compila e roda beleza sem problemas mas se preciso alteraralguma form nao da"


Se o autor da mensagem ler esse post, por favor, não se ofenda. Veja como uma crítica construtiva, ok? :) se você tivesse escrito melhor, poderia ter obtido mais respostas. E não estou me referindo apenas à sua mensagem, usei-a como exemplo, mas esse tipo de problema é bem comum na internet.

Depois de ler algumas vezes, até entendi alguma coisa, mas qualquer um com menos paciência vai descartar o email na primeira leitura, e quem mandou a mensagem vai ficar sem ajuda.

Não é preciso usar uma linguagem rebuscada, mas alguns cuidados com o texto podem melhorar o entendimento de quem lê, e no caso de uma mensagem em um fórum, fazer com que você obtenha ajuda mais facilmente. Vou deixar três dicas que podem ajudar.

  • Use pontuação. Em um texto muito grande, sem vírgulas nem ponto, não dá pra entender nada. Fica parecendo aquelas mulheres de alguns filmes que falam chorando e sem nenhum pausa e você não entende nada :).
  • Não escreva como você fala. Quando você está falando, existem uma série de fatores que não estão presentes na escrita, como entonaçao da voz, pausas e tons irônicos. No texto escrito, deve se escrever de forma que seu leitor o entenda.
  • Leia seu texto. Muitos erros e problemas podem ser corrigidos apenas com uma leitura do que você escreveu.

quarta-feira, 23 de janeiro de 2008

Enviar email pelo .Net

No framework 2.0 para cima, você pode usar a classe SmtpClient para enviar um email em sua aplicação. Veja o código abaixo:

// Cria o cliente Smtp passando o endereço e porta do host
SmtpClient client = new SmtpClient();
client.Host = "smtp.seusitedeemail.com.br";
client.Port = 25;


// Passa o usuário e a senha se o servidor SMTP requer autenticação
client.Credentials = new NetworkCredential("usuario", "senha");



// Cria a mensagem a ser enviada
MailMessage msg = new MailMessage();
msg.From = new MailAddress("fulano@email.com.br", "Fulano");
msg.To.Add(new MailAddress("email1@provedor.com.br", "Destinatário 1");
msg.To.Add(new MailAddress("email2@provedor.com.br", "Destinatário 2");


msg.Subject = "Assunto da mensagem";
msg.Body = "Corpo da mensagem";



client.Send(msg);




P.S: Se estiver usando o framework 1.1, tente esse link :

http://msdn2.microsoft.com/en-us/library/system.web.mail.smtpmail(VS.71).aspx

Nunca usei essa classe, mas parece atender às necessidades.




sábado, 19 de janeiro de 2008

DataReader vs Dataset

Lá vai eu mais uma vez tentar ressuscitar esse blog. Vamos ver se dessa vez eu consigo :)

Um tema clássico em artigos sobre .Net é a rapidez do DataReader em comparação com o Dataset carregado por um DataAdapter. Isso realmente é verdade, mas não significa que você deva substituir todos os Datasets de sua aplicação por datareaders. Dependendo da forma que está utilizando o DataReader, ele pode ter a mesma performance que um DataSet*.

Primeiro é preciso entender porquê o DataReader é mais rápido que um DataSet*. A vantagem do DataReader consiste no fato de não precisar carregar todo o conteúdo da tabela em memória, e de retornar os registros à medida que são disponibilizados pelo banco.

Quando se usa o DataSet*, todos os registros retornados são carregados em memória, para depois serem processados. Já o DataReader carrega na memória apenas o registro atual, diminuindo assim os custos de memória da aplicação. Dessa forma, porém, não é possível acessar registros anteriores.

Outra vantagem é que o DataReader retorna os registros coforme forem sendo disponibilizado pelo banco, enquanto o DataSet aguarda o término da execução da procedure para prosseguir a execução, ou seja, a aplicação ficará parada enquanto isso.

Entretando, se você estiver usando o DataReader para ler todos os registros do banco e carregá-los na memória (Que é exatamente o que o DataAdapter faz, pois ele usa um DataReader) para então processá-los, estará anulando as duas vantagens do DataReader. Nesse caso seria melhor usar um DataSet, que teria a mesma performance e requeriria menos código.

Ou seja, um DataReader só será vantajoso se você carregar na memória apenas um registro de cada vez, e processar os registros um a um, conforme os ler do DataReader.

* - Sempre que eu mencionar o DataSet nesse artigo, como em "performance do DataSet", entenda que estou falando não só do DataSet, mas do processo de usar um DataAdapter para carregar os registros do banco em um DataSet.

sexta-feira, 14 de setembro de 2007

Um Try..catch em cada método

Muitos desenvolvedores acham que o ideal é colocar um try...catch em todo método. É comum ver blocos assim :

try
{
{Código}
}
catch(Exception ex)
{
throw ex;
}

No exemplo acima, o try .. catch é inútil, pois o efeito seria exatamento o mesmo, caso não se usasse try.. catch. Nos dois casos, quando um erro ocorresse, esse erro seria lançado para o método superior, a diferença no caso do exemplo acima é que o erro seria lançado duas vezes, uma na origem do erro e outra no comando throw ex.

A própria Microsoft recomenda que o catch seja utilizado apenas quando alguma coisa for feita com a exceção, ou seja, quando a presença do try..catch fizer alguma diferença. Caso contrário será uma sobrecarga desnessária.

Concordo que seja necessário tratar todos os erros, mas isso não precisa ser feito em todas as funções, se você tratar o erro nas funções principais, os erros das subrotinas também serão capturados.

segunda-feira, 27 de agosto de 2007

Classe ReadOnlyCollection

Recentemente tive um problema que outros já podem ter tido.

Tinha uma classe com uma coleção (List<>) private que queria disponibilizar, mas queria que quem utilizasse a classe pudesse apenas ler o conteúdo da lista, sem alterá-la. Se eu simplesmente colocasse uma propriedade pública com a lista, ia permitir que alguém adicionasse ou removesse elementos dela.

Entre outras soluções que pensei para isso, descobri uma classe que ajuda bastante. A ReadOnlyCollection. Ela é na verdade um Wrapper para uma coleção. Vamos supor que você tem uma lista de string na sua classe:

private List _linhas;

Para publicá-la como somente leitura , use :

public ReadOnlyCollection Linhas
{
get { return new ReadOnlyCollection (_linhas); }
}

Vale lembrar que esse método não duplica o conteúdo da lista. Como a classe é apenas um wrapper, qualquer alteração no conteúdo da lista será refletida no objeto ReadOnlyCollection já criado.

Classe ControlPaint

Uma classe interessante para quem está trabalhando com controles Owner Draw, ou seja, desenhando na mão o conteúdo do controle, é a ControlPaint.

Ela possui métodos para facilitar o desenho de controles, como o método DrawBorder3D (Acho que não preciso dizer que esse método desenha uma borda em 3D) e métodos para desenhar botões, checkboxes etc.

sexta-feira, 17 de agosto de 2007

Breakpoints Avançados

O tradicional Breakpoint, usado para interromper a execução do sistema e permitir a depuração do sistema possui algumas opções que podem ajudar bastante.

Você já teve que depurar algum loop e ficar apertando F10 até chegar na iteração que está dando problema? Você pode configurar o breakpoint para interromper a execução somente na n-ésima vez que passar por ele. Para isso, clique com o botão direito em um breakpoint existente (Clique na bolinha vermelha) e vá em "Hit Count...". Existem algumas opções para parada, uma pra parar quando o número de passados pelo breakpoint atingir um determinado valor ou for múltiplo de um determinado número , por exemplo.

Outra opção interessante é "Condition..." , acessada do mesmo popup menu, que permite que estabeleça um condição para que o Breakpoint pare. Você pode, por exemplo, fazer com que o breakpoint pare quando um totalizador atingir determinado valor, colocando uma expressão como "total > 100". A idéia é que se a expressão que você colocar for True, o Breakpoint será interrompido.