ByVal

Uma das coisas chatas que eu considero no Visual Basic .NET é a questão do ByVal nos parametros dos procedimentos. Como todos sabem, se não especificarmos nada quando estamos criando os parametros de um determinado procedimento, por default é colocado ByVal.

Até então sem muitos problemas. Então vou lá e crio um procedimento qualquer, com um parametro do tipo ArrayList e, como não especifiquei se quero ByVal ou ByRef, o editor automaticamente embutiu o maldito ByVal. Pois bem, a questão é que mesmo com ByVal, se eu passar o meu objeto ArrayList para o procedimento e dentro dele alterar esse objeto, como adicionar ou remover elementos, isso refletirá no meu objeto original, ou seja, o comportamento é ByRef.

Isso funciona da mesma forma para tudo o que são objetos no .NET, com excessão dos value-types. Mesmo sem a keyword ByRef, se o objeto sofrer alguma alteração, isso será considerado, já que apontará para o mesmo local – objetos sempre serão ByRef. Será que não havia uma forma de automatizar isso, pois ficaria muito mais legível e de fácil entendimento.

Operador ??

Dando uma olhada no Help do Visual Studio 2005 Beta 2, encontrei um novo operador dentro da linguagem C#. Trata-se do ??. Um exemplo do uso do mesmo, é mostrado abaixo:

     int x = 2;
     int? y = null;

     int z = x ?? y;
     Console.WriteLine(z.ToString());

O sintaxe retorna o valor que está definido do lado esquerdo do operador se o mesmo não for nulo. Caso contrário, o valor que está definido do lado direito do operador é retornado. O output do código acima retorna 2, pois y está definido como nulo. Se alterarmos o valor de y de nulo para algum outro valor válido (inteiro), o valor dele será atribuido à z e, consequentemente exibido.

Para quem quiser saber mais sobre Nullable Types, acesse este link.

Operadores is e as

Depois de 3 e-mails recebidos em menos de 1 mes, onde colegas me perguntaram para que serve e qual a diferença entre os operadores is e as do C#, resolvi postar aqui a resposta que enviei à eles e, assim contribuir com os demais colegas que possam ter a mesma dúvida.

Operador is:
Este operador verifica se objeto é compatível com um determinado tipo, e o resultado desta avaliação é um valor booleano (True ou False). A vantagem deste operador é que ele nunca lançará uma Exception, mesmo quando os tipos não forem compatíveis. O código abaixo demonstra isso:

     public class Cliente{}
     //….
     object obj = new Object();
     bool teste1 = (obj is Object); // Retorna True
     bool teste2 = (obj is Cliente); // Retorna False

Assim sendo, podemos ter um if comparando se o tipo é compatível com outro e sendo, fazermos o cast (conversão):

     if(obj is Cliente){
          Cliente c = (Cliente)o;
          //….
     }

O único problema deste código é que o CLR verificará o tipo do objeto duas vezes, ou seja, na condicional o operador is fará essa verificação e, logo após, passando por esta verificação e agora já dentro do bloco if antes da conversão ser feita, uma nova verificação é realizada perdendo assim em performance.

Operador as:
É neste caso que o operador as entra em ação. Ele verifica se o objeto é compatível com o tipo Cliente e, se for, o operador retorna um ponteiro (não nulo) para este objeto. Se caso o tipo não for compatível, então como o operador is, também é retornado nulo. Com isso, o tipo só é verificado uma vez. O código abaixo exemplifica o uso do operador as e comprova o ganho no desempenho:

     Cliente c = obj as Cliente;
     if(c != null){
          //….
     }

Lembre-se que a verificação (if) se faz necessário, pois caso o objeto for incompatível, o operador as retornará nulo, e uma Exception do tipo System.NullReferenceException será atirada ao cliente.

Nota: Felizmente no VB.NET 2005 teremos também um operador semelhante: o TryCast, como é explicado neste post.

Formatando valores em colunas do DataGrid

Frequentemente quando utilizamos um controle do tipo DataGrid, e inserimos valores do tipo Data, Dinheiro, Inteiros ou Decimais, precisamos formatar esse valor de acordo com a finalidade desse Campo. Nesse artigo apresentarei a propriedade DataFormatString da BoundColumn de um DataGrid.

Existem dois tipos de formatação: Standard Formats e Custom Formats. Como o objetivo do artigo é mostrar as formatações mais utilizadas em aplicativos para serem executados nos padrões brasileiros, então deixarei claro o seguinte: O padrão para valores numéricos será adotado o Stardand Format. Já a formatação para datas, será utilizado o Custom Format.

A propriedade DataFormatString fornece uma formatação customizada para o valor inserido na BoundColumn. Esta propriedade consiste em duas partes separadas por dois pontos estando dentro de um par de chaves da seguinte forma: {:}. Isso é válido apenas quando estiver inserindo na BoundColumn valores numéricos ou do tipo data.

A sintaxe é a seguinte: {0:[Formato][Qtde. Casas Decimais]}. O caracter que vem após os dois pontos, é o formato em que o valor será exibido. Você também poderá optar por definir a quantidade de casas decimais da seguinte forma: {0:C2}. A seguir uma lista com os valores possíveis:

Standard Format Descrição
C Exibe o valor no formato de moeda.
D Exibe o valor em formato decimal.
E Exibe o valor no formato cientìfico (exponencial).
F Exibe o valor no formato fixo.
G Exibe o valor no formato geral.
N Exibe o valor no formato numérico.
P Exibe o valor no formato de porcentagem.
X Exibe o valor no formato hexadecimal.

Observações: Os caracteres acima que especificam o formato a ser exibido não são case-sensitive, exceto para o X, pois se ele for minúsculo, os valores serão apresentados em minúsculo, do contrário, serão exibidos em maiúsculo.

Para configurar os valores no DataGrid, clique com o botão direito do mouse em cima do mesmo, e selecione Property Builder. Em seguida, vá até a aba Columns e ao incluir uma nova BoundColumn, a propriedade DataFormatString será habilitada para que você possa definir a formatação customizada. A imagem abaixo ilustra o processo:

Figura 1 – Configurando a propriedade DataFormatString do DataGrid.

A figura abaixo exibe os valores no DataGrid de acordo com a formatação pré-definida na propriedade DataFormatString.

Figura 2 – Configurando a propriedade DataFormatString do DataGrid.

Aqui chamo a atenção para a coluna onde é exibido o valor no formato moeda e o separador de casas decimais. Como não foi definido nenhuma cultura no arquivo Web.Config, por padrão ele adota as configurações regionais definidas no servidor. Se acrescentar a cultura pt-BR nas configurações de nossa aplicação, verão que os valores passarão a serem exibidos no formato brasileiro. Abaixo a ilustrução deixará claro:

1
 
<globalization requestEncoding=”utf-8″ responseEncoding=”utf-8″ culture=”pt-br” />
 
Código 1 – Alterando a cultura no arquivo Web.Config.

Com essa mudança, agora temos os valores sendo exibidos no padrão brasileiro, conforme mostrado na figura 3:

Figura 3 – Valores sendo exibidos no formato brasileiro.

Além das configurações para valores numéricos, ainda podemos utilizar a propriedade DataFormatString para formatarmos datas que são inseridas no DataGrid. Abaixo uma tabela as as possibilidades de formatação para datas:

Custom Format Descrição
MM/dd/yyyy Formato Mês/Dia/Ano
dd/MM/yyyy Formato Dia/Mês/Ano
hh:mm Formato Hora:Minuto
hh:mm:ss Formato Hora:Minuto:Segundo
dd/MM/yyyy hh:mm:ss Formato Dia/Mês/Ano Hora:Minuto:Segundo

OBSERVAÇÕES: Devemos nos atentarmos para o MM e para o mm, pois maiúsculo significa Mês, já o minúsculo significa Minutos.

Há ainda vários outros padrões para a formatação de datas, quais não optei por colocar aqui por que utilizamos na maioria das vezes o formato brasileiro. Mas para quem se interessar pode encontrar maiores informações no link direto da fonte da Microsoft: Standard DateTime Format Strings.

Como dito anteriormente, a configuração da formatação para data, funciona da mesma forma que a formatação para valores numéricos, ou seja, você define na propriedade DataFormatString da BoundColumn do DataGrid, como por exemplo: {0:dd/MM/yyyy hh:mm:ss}. A Figura 4 ilustra os possíveis formatos para datas:

Figura 4 – Formatando Datas.

IMPORTANTE: Você poderia também ao invés de barras “/” utilizar o hífen “-” como separador para as Datas, ficando a String de formatação da seguinte forma: {0:dd-MM-yyyy hh:mm:ss}.

Poderá também fazer a formatação diretamente no HTML, utilizando a propriedade DataItem em conjunto com a método Format. Exemplo:

1
2
3
 
<asp:TemplateColumn>
    <%# String.Format(“{0:c}”, Convert.ToInt32(Container.DataItem(“NomeDaColuna”))) %>
</asp:TemplateColumn>
 
Código 2 – Formatando valores diretamente no código HTML.

CONCLUSÃO: Com este artigo mostrei as possíveis formas de formatação para valores do tipo numéricos de datas que são inseridos nas BoundColumns do DataGrid. Aconselho a darem uma olhada também no link que coloquei um pouco mais acima que diz respeito à outros tipos de formatação bastante utilizados pelas aplicações.

FormatandoValores.zip (19.08 kb)

Try Catch “Quando”…

Encontrei uma feature no Visual Basic .NET que particularmente até hoje nunca utilizei, mas achei bastante interessante. Trata-se da condição When em um bloco Catch do tratamento de exceções. Através desta condicional, definimos se a Exception que foi gerada pelo código que estava sendo gerenciado pelo bloco Try irá ou não ser tratada. Para exemplificar, veja o código abaixo:

        Dim gerarException As BooleanTrue
        Try
            Throw New Exception(“Erro na aplicação!”)
        Catch ex As Exception When gerarException
            Console.WriteLine(“Erro na Aplicação, mas foi tratado.”)
        End Try

Analisando o código acima vemos que uma Exception é gerada dentro do bloco Try. Se a variável booleana estiver definida como True, o bloco Catch que trata a Exception será executado, do contrário a mesma é atirada na tela, mas claro, isso baseando-se no código do exemplo acima.

My Classes no C#

Sim, apesar de não ser intrinsicamente do C#, ou seja, a Microsoft somente disponibilizou isso no Visual Basic .NET, no site IDesign.net tem um wrapper que utiliza as classes My do próprio Visual Basic .NET e assim, podemos consumí-las no C#. O autor deu o nome de “That” para esta classe e um exemplo do uso dela em C#, seria:

     this.RichTextBox1.Text = That.Computer.FileSystem.ReadAllText(“Arquivo.txt”);

Para que quiser baixar o projeto, está aqui o link.

foreach – C#

Nesta nova versão da linguagem C#, temos novas formas de percorrermos Arrays. Nas versões anteriores (1.x), faríamos algo do tipo:

     string[] categorias = new string[] {“ASP.NET”, “VB.NET”, “C#”}
     foreach(string s in categorias)
          Console.WriteLine(s);

Agora temos duas opções para isso: utilizarmos o método ForEach da classe Array com um método auxiliar para processar o que queremos fazer com cada elemento do Array ou mesmo utilizando métodos anonimos:

     [ Usando um método auxiliar ]
     string[] categorias = new string[] {“ASP.NET”, “VB.NET”, “C#”}
     Array.ForEach(categorias, Escrever);
     //…
     private void Escrever(string s){
          Console.WriteLine(s);
     }

     [ Usando um método anonimo ]
     string[] categorias = new string[] {“ASP.NET”, “VB.NET”, “C#”}
     Array.ForEach(categorias, delegate(string s)
     {
          Console.WriteLine(s);
     });

Eu custei a entender esses métodos anonimos, e particularmente agora, um pouco mais acostumado com eles acho mais prático que a criação de um método auxiliar.

C# 3.0 – Language Innovations

Agora que estou me habituando no C# 2.0, já vem o 3.0: http://msdn.microsoft.com/events/pdc/agenda/default.aspx

From Visual Basic to Visual C# to Visual C++, from compiler internals to architecture diagrams, from build to test, join the product team in this set of sessions to learn how Visual Studio, the .NET Framework, and WinFX are evolving to meet your software development lifecycle needs. Microsoft architects, program managers, and developers will drill into programming language enhancements, software development lifecycle management with Visual Studio Team System, Visual Studio productivity features, Office and application programmability, and the new unified build system. Whether you’re writing Win32 code, MFC code, or managed code, this track has something new for you.
  • C# 3.0 Language Innovations
  • C++ Interop: Under the Hood
  • Visual Basic Language Innovations
  • Visual Basic: Under the Hood
  • Visual Studio Team System: Bringing Development and Test Together for Building and Testing Distributed Applications
  • Monad: Bringing Scripting and Extensibility to Your Build Environment
  • Enabling Rich Design-time Support for Your Custom Avalon Controls in Visual Studio

TryCast Operator

Na nova versão da linguagem Visual Basic .NET foi introduzida o “novo” operador chamado TryCast, que até o momento, era somente visto em códigos do .NET Framework que eram decompilados pelo Reflector e não podia ser utilizado em aplicações que nós mesmo desenvolvemos.

Ela é usada como utilizamos atualmente os operadores CType ou o DirectCast, ou seja, passamos o objeto que queremos converter e o tipo para qual este deve ser convertido. Mas a diferença é que o TryCast somente trabalha com References Types, como Classes e Interfaces. E também vale lembrar que ele requer herança ou implementação entre os dois tipos.

Ao contrário do CType e DirectCast, que atiram uma InvalidCastException quando não é possível a conversão, o TryCast retorna Nothing. Abaixo, um exemplo do uso deste novo operador:

          Public Sub Teste(ByVal obj As Object)
               Dim colecao As IList = TryCast(obj, IList)
               If Not (colecao Is Nothing) Then
                    Console.WriteLine(“Coleção válida.”)
               End If
          End Sub

Isso já é suportado no C#, onde lá é conhecido como operador “as“.

Static Classes

Com a nova versão do .NET (2.0), temos agora no C# as chamadas Static Classes, onde é possível declarar uma classe como estática e assim ter todos os seus membros também estáticos, evitando assim a criação de uma classe sealed com o construtor privado e além disso, já informará caso, por engano, voce coloque um método de instancia dentro de uma classe estática. A sintaxe fica agora parecida como:

          public static class MinhaClasse{
               public static void MeuMetodo(){
                    //…
               }
          }

Depois dizem que o C# não copia o VB.NET 😛