.NET Tips And Tricks
Artigos com o marcador C#
Atributo DebuggerDisplay
06/09/10
Olá, tudo bem?
No nosso trabalho, passamos boa parte do tempo debugando, ou depurando
aplicações, postei dois artigos sobre as novidades na depuração de código no Visual Studio 2010,aqui, aqui e aqui.
Esse três artigos que publiquei, mostram recursos do Visual Studio 2010, mas desde a versão 2.0 do .NET Framework, temos um atributo chamado DebuggerDisplay.
Com o DebuggerDisplay conseguimos definir, o que gostaríamos de ver facilmente, na janela onde podemos navegar entre as propriedades de uma classe durante a depuração do código.
Detalhe que o atributo não está limitado ao C#, podemos utilizar tranquilamento com VB.NET, F# e C++.
Vamos imaginar a classe Posicao abaixo, onde eu armazeno o valor X e Y de um determinado objeto de um jogo por exemplo.
class Posicao
{
public int X { get; set; }
public int Y { get; set; }
}
Agora instanciamos a classe, e definimos alguns valores.
static void Main(string[] args)
{
var posicao = new Posicao {X = 50, Y = 100};
}
Essa é uma classe simples, mas da para ver bem o funcionamento do DebuggerDisplay. Agora compilando o programa, e depurando o mesmo, quero descobrir o valor de X e Y, então eu dependo da janela Locals onde posso navegar nas propriedades do objeto, ou navegando nos menus abertos sobre o objeto ao passar o mouse pelo mesmo.
Na imagem acima, da para ver que a coluna value, da janela Locals mostra o tipo do meu objeto, que nesse caso é OperadoresCSharp.Posicao, o mesmo ocorre com o menu flutuante, em ambos os casos eu preciso expandir o objeto para ver os valores das propriedades.
Agora utilizando o atributo DebuggerDisplay, que está no namespace System.Diagnostics eu consigo definir, por exemplo, quais propriedades da minha classe eu quero mostrar diretamente no lugar onde é mostrado o tipo do objeto.
[DebuggerDisplay("{X} {Y}")]
class Posicao
{
public int X { get; set; }
public int Y { get; set; }
}
No atributo, eu consigo colocar entre {} o nome de uma propriedade, que é o que fiz, agora na depuração já melhorou um pouco.
Já melhorou, só que ainda não é o ideal, o que é 50, 100? Só estou mostrando os valores das propriedades, mas não sei de qual propriedade é o valor 50 ou 100, felizmente conseguimos “nomear”, e fazer algo assim X = {X}.
[DebuggerDisplay("X={X} Y={Y}")]
class Posicao
{
public int X { get; set; }
public int Y { get; set; }
}
Agora sim, na hora de depurar o código, fica mais claro saber que o 50 é do X e 100 é do Y.
Mas isso funciona só com propriedades? Felizmente não, vamos imaginar que por algum motivo, é importante saber a soma de X e Y, e eu possuo um método chamado SomarValores(), consigo utilizar a mesma sintaxe passando ao invés do nome da propriedade, o nome do método, veja abaixo.
[DebuggerDisplay("X={X} Y={Y} Soma dos valores = {SomarValores()}")]
class Posicao
{
public int X { get; set; }
public int Y { get; set; }
public int SomarValores()
{
return X + Y;
}
}
Muito simples e útil, colocando um simples atributo, consigo definir valores úteis, que ajudem na hora da depuração do projeto.
Para finalziar, o atributo não está limitado a classes, posso utilizar com.
- Classes
- Structs
- Delegates
- Enumeradores
- Campos
- Propriedades
- Assemblies
Abraços e até o próximo post.
C#– Keyword Partial
02/09/10
Olá pessoal, tudo bem?
Tudo muito agitado por aqui, mas voltei a dar atenção ao blog finalmente!! E além de continuar postando sobre Silverlight, Windows Phone 7, vou continuar mostrando alguns truques que podemos utilizar no C#, como os operadores pouco utilizados que já mostrei aqui e aqui.
Hoje vou falar sobre a keyword partial.
Com a keyword partial conseguimos dividir uma mesma classe, struct ou interface em mais de um arquivo. Mas quando o projeto é compilado e o código gerado, esses arquivos são “mesclados”. Quem trabalha com Windows Forms e ainda não viu, veja que um formulário é dividido em vários arquivos mas utilizando partial.
Dividir as classes em vários arquivos, pode ser útil em projetos ou classes grandes, não preciso abrir aquela classe com 100 métodos (alguém tem algo assim?
), ou como eu mostrei aqui no exemplo onde utilizo validação com DataAnnotations no LINQ To SQL só consigo fazer esse tipo de “truque” graças as classes parciais.
Bom chega de falar e vamos aos exemplos que é muito melhor.
Uma classe Calculadora com 4 métodos simples.
class Calculadora
{
public int Somar(int valor1, int valor2)
{
return valor1 + valor2;
}
public int Diminuir(int valor1, int valor2)
{
return valor1 - valor2;
}
public int Multiplicar(int valor1, int valor2)
{
return valor1 * valor2;
}
public int Dividir(int valor1, int valor2)
{
return valor1 / valor2;
}
}
Posso dividir essa classe em duas da seguinte forma.
partial class Calculadora
{
public int Somar(int valor1, int valor2)
{
return valor1 + valor2;
}
public int Diminuir(int valor1, int valor2)
{
return valor1 - valor2;
}
}
partial class Calculadora
{
public int Multiplicar(int valor1, int valor2)
{
return valor1 * valor2;
}
public int Dividir(int valor1, int valor2)
{
return valor1 / valor2;
}
}
Uma dúvida frequente, é se as classes precisam estar no mesmo Arquivo.cs, e a resposta é não, posso ter vários arquivos.cs com nomes diferentes contendo cada um, um pedaço da minha classe parcial.
Outro detalhe, é que para ele mesclar as classes, elas devem pertencer ao mesmo namespace.
Só para mostrar o código IL gerado, vemos que só existe uma classe Calculadora com os 4 métodos, mesmo dividindo o código em duas classes parciais.
E não tenho restrições quanto a herança e implementação de interfaces. Veja o código abaixo.
class PessoaFisica : Pessoa, IDisposable
{
public void Dispose()
{
throw new NotImplementedException();
}
}
Esse código poderia ser dividido da seguinte forma.
partial class PessoaFisica : Pessoa
{
}
partial class PessoaFisica : IDisposable
{
public void Dispose()
{
throw new NotImplementedException();
}
}
Uma keyword simples, que pode ser muito útil na organização de determinados projetos.
Abraços e até o próximo artigo.
Ribbon para WPF
03/08/10
Desde que a Microsoft lançou o menu Ribbon no Office, creio que foi amor a primeira vista com a maioria das pessoas, apesar de muito diferente daquele velho e bom menu padrão, utilizando Ribbon, tudo fica mais organizado.
Infelizmente o WPF não possuia o menu Ribbon nativo para utilizarmos em nossos projetos, digo nativamente por que com componentes de terceiros, como por semplo da Telerik, eu já utilizei Ribbon eu vários projetos.
Ontem, dia 02/08 foi liberado o RTM do Ribbon for WPF um menu do estilo Ribbon, para WPF, construído pela própria Microsoft, já utilizei esse menu a algum tempo, mas ainda era Beta e não funcionou bem.
Para começar, podemos fazer download do menu clicando aqui, temos a opção de fazer download do instalador do Ribbon, e também de exemplos de utilização e do código fonte, isso mesmo, podemos olhar o código fonte do projeto, bons estudos
. Além do link para download, clicando aqui vemos a página de documentação do menu.
A primeira mudança quando instalamos o Ribbon, é que ganhamos um novo tipo de projeto para WPF Ribbon Application.
Com o projeto criado, por padrão é criado um menu com itens básicos, o que é muito bom para entender o funcionamento do controle. Abaixo imagem do menu padrão criado com o código gerado.
<ribbon:Ribbon x:Name="Ribbon">
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu SmallImageSource="Images\SmallIcon.png">
<ribbon:RibbonApplicationMenuItem Header="Hello _Ribbon"
x:Name="MenuItem1"
ImageSource="Images\LargeIcon.png"/>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonTab x:Name="HomeTab"
Header="Home">
<ribbon:RibbonGroup x:Name="Group1"
Header="Group1">
<ribbon:RibbonButton x:Name="Button1"
LargeImageSource="Images\LargeIcon.png"
Label="Button1" />
<ribbon:RibbonButton x:Name="Button2"
SmallImageSource="Images\SmallIcon.png"
Label="Button2" />
<ribbon:RibbonButton x:Name="Button3"
SmallImageSource="Images\SmallIcon.png"
Label="Button3" />
<ribbon:RibbonButton x:Name="Button4"
SmallImageSource="Images\SmallIcon.png"
Label="Button4" />
</ribbon:RibbonGroup>
</ribbon:RibbonTab>
</ribbon:Ribbon>
Como podem ver, não existe segredo na criação de Tabs, Grupos e Botões. Agora conseguimos utilizar um ótimo menu com Ribbon, sem recorrer a outras empresas.
Um outro detalhe, é que na Toolbox do Visual Studio, uma nova aba é criada, com todos os controles disponíveis para a criação do menu com Ribbon.
Aproveitem o Ribbon for WPF e é hora de começar a repensar a estrutura dos menus das aplicações
.
Abraços.
Melhorando WinApps seguindo WebApps
01/08/10
Nossa Márcio que título maluco!!
Pois é, foi o melhor que encontrei
mas logo o título fará sentido. Felizmente, sempre trabalhei com Web e Windows, apesar de não ter tanto talento como designer, adoro estudar padrões para UI, o que é certo, errado, o que fazer e o que não fazer.
É claro que não vou falar que todos os sites ou todas aplicações web seguem o que vou mostrar, mas felizmente a maioria das “bem feitas” seguem isso. Vou esquecer sites normais, e vou focar em aplicações web, só para facilitar.
O item que estou falando é tão simples e básico, que todo mundo deveria seguir, que é alinhar corretamente os itens de um formulário, é tão comum quando vamos desenvolver um layout de site, utilizar grids para definir o espaçamento entre os itens, assim temos um layout organizado e agradável.
Quem liga para isso Márcio? Ahhh ninguém, é só mais uma prática boba que o pessoal segue. Todo mundo liga, e liga muito. Mesmo que mesmo sem perceber, um formulário bem organizado ajuda qualquer usuário a encontrar o que ele quer.
Quem nunca viu algum profissional falar algo do tipo, “meu cliente não acha nada, meu cliente não procura nada direito”, é tão fácil culpar o cliente, afinal “eu” fiz tal coisa, então essa coisa está “perfeita”.
Mas eu acho que isso é meio cultural, já cansei de passar estudos de como criar um layout agradável para formulários para programadores, o que eles fazem? Apertam delete no e-mail, afinal isso é trabalho do “designer”, eu acho isso um absurdo, não estou pedindo para algum programador de WinApps aprender como combinar cores, como utilizar o Photoshop, nada disso, mas só para prestar atenção em como organizar um formulário.
Chega de falar, e vamos ver dois exemplos, com Windows Forms mesmo, que é o que a maioria do pessoal utiliza
.
Padrão macarronada, nem sei se alguém já deu esse nome, mas falei ontem em um curso e gostei
.
Ok, a tela feita, funciona, mas eu acho horrível olhar telas dessa forma, podemos facilmente organizar da seguinte forma.
Olhando a imagem acima, sei onde tudo começa e acaba, tenho padrão de espaçamento entre os campos do formulário, joguei o Label acima dos campos só para facilitar a visualização, e prefiro assim, mas com o Label a esquerda funciona da mesma forma.
Quando eu trabalhava com o Heitor Althmann, é família de geek =D, ele é designer, nós criamos alguns padrões para formulários, na época definidos por CSS automaticamente, mas ainda utilizo o padrão com sucesso em aplicações para Windows. Segue abaixo a lista de possibilidades com o padrão.
Espero que gostem, e que utilizem o padrão, e que UI seja uma preocupação também de quem desenvolve aplicações para Windows, afinal, aquela tela com 100 campos, totalmente desorganizados, deixa qualquer usuário confuso.
Abraços.
C# – Operador ?:
25/07/10
Continuando a série onde falei sobre o operador ?? hoje vou mostrar o operador ?: que também gosto e utilizo muito.
A regra para esse operador é simples.
condição ? primeira expressão : segunda expressão;
Mas espera um pouco Márcio, isso parece um if/else feito em uma linha só. É isso mesmo
. Galera do VB vai lembra da função IIf.
Então vamos ver um código simples, onde escrevemos na tela se uma pessoa pode votar ou não dependendo da idade. Primeiro com if/else.
static void Main(string[] args)
{
var idade = 26;
if(idade >= 16)
Console.WriteLine("Pode votar!");
else
Console.WriteLine("Não pode votar!");
}
Um código simples, mas eu prefiro escrever esse código utilizando o operador ?: que fica seguinte forma.
static void Main(string[] args)
{
var idade = 26;
Console.WriteLine(idade >= 16 ? "Pode votar!" : "Não pode votar!");
}
Esse é um operador um pouco polemico, algumas pessoas não gostam, acham que o código fica mais complexo, eu não concordo, mas é tema para uma boa discussão.
Abraços.
C#–Operador ??
14/07/10
Existem vários operadores disponíveis, e um que gosto muito é o operador ??.
Resolvi mostra-lo porque dificilmente eu vejo alguém utilizando, será que só eu gosto? Bom, como sabemos temos no .NET os Nullable Types, ou sejá conseguimos definir por exemplo um int que pode receber null.
Abaixo as duas formas possíveis para definir que um tipo pode receber null.
int? mes = null; Nullable<int> ano = null;
Para facilitar, e uma preferência, utilizo sempre int?, DateTime?, bool?, etc… bem melhor que Nullable<T>.
Um exemplo da utilização do operador para entendermos o funcionamento.
static void Main(string[] args)
{
int? dia = 14;
int? mes = 7;
Nullable<int> ano = null;
Console.WriteLine("Dia: {0} Mês: {1} Ano: {2}", dia ?? 0, mes ?? 0, ano ?? 0);
}
Análisando o código acima, escrevo na tela o dia, mês e ano informados, se algum for null mostro 0.
Então o funcionamento do operador ?? é:
Mostra o operando da esquerda do operador ?? se o mesmo não for nulo, se o operando da esquerda for nulo, mostra o da direita.
Simples e extremamente útil, espero que gostem e adotem mais um operador
.
Abraços.
Biblioteca de IO para Silverlight 4 e COM+
11/07/10
Um dos novos recursos do Silverlight 4, quando temos aplicações rodando for a do Browser é utilizar componentes COM+.
Pode parecer estranho falar de COM+, imaginem uma aplicação instalada no computador do usuário, não temos acesso direto aos arquivos do PC por exemplo, é ai que entra o COM+, vamos trabalhar com componentes que farão esse serviço. E acessar arquivos é só um dos exemplos
.
Lembrando que, a aplicação deverá rodar com nível de privilégio elevado, por questões óbvias de segurança
.
Não é difícil trabalhar com esses componentes COM+, mas temos que conhecer os nomes dos métodos e propriedades que cada componente possui, e como estaremos trabalhando com dynamic, o Intellisense não vai ajudar.
Foi pensando nisso que resolvi hospedar no CodePlex meus projetos e estudos, e resolvi criar uma biblioteca de IO para trabalhar com o FileSystemObject do COM+, e ficar mais transparente para o programador trabalhar com arquivos e diretórios.
Estou implementando primeiramente as classes File e Directory, e trabalhar com essas classes será da mesma forma das respectivas classes do namespace System.IO. Por isso vou manter os nomes em inglês tanto para classes e métodos.
Agora vamos ver como utilizamos COM+ em uma aplicação OOB (Out Of Browser) feita com Silverlight 4.
Primeiro passo é definir nas propriedades do projeto que a aplicação pode rodar fora do browser, e nas configurações falar que a aplicação roda sobre privilégios elevados.
O próximo passo é adicionar referência a Microsoft.CSharp.dll, encontrará essa .dll no diretório de SDK´s, veja abaixo o diretório do meu computador C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\Microsoft.CSharp.dll
Abaixo um exemplo de código utilizando COM+ verifico se um determinado arquivo existe ou não, e informo ao usuário.
using (dynamic fileSystemObject = AutomationFactory.CreateObject("Scripting.FileSystemObject"))
{
if (fileSystemObject.FileExists(path))
MessageBox.Show("Arquivo existe");
else
MessageBox.Show("Arquivo não existe");
}
Como disse anteriormente não é um código complexo, mas temos que saber o nome do método que é FileExists, temos que utilizar a classe AutomationFactory do namespace System.Runtime.InteropServices que cria uma objeto pelo nome do mesmo, no caso para trabalhar com arquivos e diretórios é “Scripting.FileSystemObject”.
Utilizando a biblioteca que eu estou criando o código fica.
if (File.Exists("d:\\Arquivo.txt"))
MessageBox.Show("Arquivo existe");
else
MessageBox.Show("Arquivo não existe");
Toda a comunicação com COM+ está encapsulada, não é necessário o conhecimento de qual método chamar, qual classe instanciar.
Até o momento implementei alguns métodos somente, principalmente pelo motivo que já falei aqui no blog que meu braço está machucado, mas o projeto é aberto, está hospedado no CodePlex, quem quiser contribuir, dar dicas, sugestões, criticas por favor fique a vontade, qualquer ajuda é bem vinda!!! ![]()
Clique aqui para acessar o projeto no CodePlex, e quem quiser contribuir entre em contato que cadastro como contribuidor.
Espero que gostem do projeto.
Abraços.
Integração C# + Ruby
28/06/10
A linguagem Ruby vem ganhando muito espaço no mercado, talvez a linguagem dinâmica mais badalada atualmente, mas o objetivo do artigo não é ensinar Ruby, vuo mostrar como podemos integrar o C# com o Ruby.
Como não vou ensinar Ruby aqui, vou deixar aqui uma dica de quem considero referência quando o assunto é .NET + Ruby, que é o site do Vinicius Quaiato, ele também está estudando bastante o assunto, e sempre conversamos a respeito. Muito do que mostrarei aqui ele postou no blog dele, e claro tenho autorização do mesmo para utilizar alguns códigos dele aqui.
Eu sempre pensei que algumas partes dos softwares que desenvolvemos, deveriam ser mais flexíveis, o que eu quero dizer como flexível é o usuário, ou alguém de um setor de suporte, ou mesmo desenvolvedores, alterarem uma regra de negócio da aplicação sem precisar recompilar o software, abrir o Visual Studio e por ai vai.
Não vou entra no mérito da questão se o usuário vai entender o código, vai saber o que escrever, não vem ao caso, criar um parser de ruby ou outra linguagem para algo mais simples não é tão complicado.
Chega de falar, e vamos ao que interessa.
O primeiro passo é instalar o IronRuby.
Depois de instalado, referênciar as 3 .dll´s abaixo, que ficam no diretório bin da instalação do IronRuby.
- IronRuby.dll
- IronRuby.Libraries.dll
- Microsoft.Scripting.dll
A primeira classe que temos é chamada de EngineRuby que utiliza o padrão Singleton para armazenar uma instância da classe ScriptEngine que está disponível no namespace Microsoft.Scripting.Hosting.
A classe EngineRuby também tem um método ObterObjeto que recebe como parâmetro o nome do arquivo Ruby que contém a classe feita em Ruby que vamos utilizar, e o nome da classe feita com Ruby. Esse método retorna um tpo dinâmico do C#, atenção a keyword dynamic.
Para facilitar o entendimento, a idéia é ter uma pasta chamada Ruby no diretório da aplicação onde vamos armazenar os arquivos .rb do Ruby.
public static class EngineRuby
{
private static ScriptEngine rubyEngine;
private static ScriptEngine CriarEngine()
{
if(rubyEngine == null)
rubyEngine = Ruby.CreateEngine();
return rubyEngine;
}
public static dynamic ObterObjeto(string nomeDoArquivo, string nomeDaClasse)
{
var diretorioDaAplicacao = Path.GetDirectoryName(typeof (EngineRuby).Assembly.Location);
var arquivo = Path.Combine(diretorioDaAplicacao, String.Format("Ruby\\{0}.rb", nomeDoArquivo));
CriarEngine().ExecuteFile(arquivo);
dynamic objeto = CriarEngine().Runtime.Globals.GetVariable(nomeDaClasse);
return CriarEngine().Operations.CreateInstance(objeto);
}
}
Bom, antes de continuar vamos falar do arquivo Ruby, para desenvolvedor códigos em Ruby, eu utilizo o RubyMine da JetBrains. É o melhor editor que encontrei até o momento.
O código é simples, uma classe chamada Boletim que possui um método Media. Passo para o método nota para os 4 bimestres, e divido a soma por 4, uma média simples, o que faremos no decorrer do artigo é alterar essa regra de calculo da média diretamente pelo aplicativo de exemplo.
Segue o código.
class Boletim
def Media(primeiroBimestre, segundoBimestre, terceiroBimestre, quartoBimestre)
(primeiroBimestre + segundoBimestre + terceiroBimestre + quartoBimestre) / 4
end
end
Agora teremos uma classe Boletim escrita em C#, que vai armazenar algumas informações como o nome do arquivo Ruby referente, e o nome da classe em Ruby.
public class Boletim
{
private static string NomeDaClasse = "Boletim";
private static string NomeDoArquivo = "Boletim";
private static dynamic Objeto
{
get
{
return EngineRuby.ObterObjeto(NomeDoArquivo, NomeDaClasse);
}
}
public static double Media(double primeiroBimestre, double segundoBimestre, double terceiroBimestre, double quartoBimestre)
{
return Objeto.Media(primeiroBimestre, segundoBimestre, terceiroBimestre, quartoBimestre);
}
}
Bom para quem viu o artigo do Vinicius Quaiato, eu modifiquei a propriedade Objeto, no caso dele, novamente ele utilizar o padrão Singleton eu não faço isso aqui por que quero alterar o código Ruby rodando meu aplicativo, e a próxima vez que o mesmo for executado quero executar as alterações no código.
Agora a parte fácil, crio uma tela onde consigo informar as notas para cadas bimestre, um botão para calcular a média e mostro o restultando.
O código que é executado quando o botão Calcular é pressionado é simples.
private void button1_Click(object sender, RoutedEventArgs e)
{
txtMedia.Text = Boletim.Media(
double.Parse(txtPrimeiroBimestre.Text),
double.Parse(txtSegundoBimestre.Text),
double.Parse(txtTerceiroBimestre.Text),
double.Parse(txtQuartoBimestre.Text)
).ToString();
}
Reparem na imagem acima, que ao lado do botão Calcular tem outro botão, clicando nesse botão uma tela será aberta mostrando o código do arquivo Ruby que possui a regra para a média do boletim.
O código dessa tela é simples, segue o código completo, mas basicamente só possui leitura e escrita de arquivo
.
public partial class EditorDeCodigo : Window
{
public string NomeDoArquivo { get; set; }
public EditorDeCodigo()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
LerArquivo();
}
private void btnCancelar_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void btnGravarAlteracoes_Click(object sender, RoutedEventArgs e)
{
SalvarArquivo();
Close();
}
private string ObterArquivo()
{
var diretorioDaAplicacao = System.IO.Path.GetDirectoryName(typeof(EngineRuby).Assembly.Location);
return System.IO.Path.Combine(diretorioDaAplicacao, String.Format("Ruby\\{0}.rb", NomeDoArquivo));
}
private void LerArquivo()
{
using (var textReader = new StreamReader(ObterArquivo()))
{
txtCodigo.Text = textReader.ReadToEnd();
textReader.Close();
}
}
private void SalvarArquivo()
{
using (var textWriter = new StreamWriter(ObterArquivo()))
{
textWriter.Write(txtCodigo.Text);
textWriter.Close();
}
}
}
Abaixo imagem da edição do código Ruby durante a execução do aplicativo.
Acho que um vídeo é o ideal para mostrar a idéia funcionando, então vejam abaixo um pequeno vídeo com a execução do aplicativo.
Integração C# + Ruby from Márcio Fábio Althmann on Vimeo.
Essa foi uma pequena amostra de como podemos utilizar essa integração do C# + Ruby, o download da solução pode ser feito abaixo.
Abraços.
Depuração de código no Visual Studio 2010 – Breakpoint Labels
24/06/10
Continuando a série sobre depuração de código no Visual Studio 2010, onde já postei a parte 01 e parte 02, hoje vou mostrar um recurso bem simples, mas útil para organizar nossos breakpoints.
Com os Breakpoint Labels, conseguimos dar um nome ou uma descrição ao breakpoint, por exemplo conseguimos organizar por modulos, cadastros, funcionalidades.
Abaixo uma tabela de quais versões do Visual Studio 2010 e quais linguagens o recurso está disponível.
| Edição | Visual Basic | C# | F# | C++ | Web Developer |
| Express | Não | Não | Não | Sim | Não |
| Pro, Premium e Ultimate | Sim | Sim | Não | Sim | Sim |
Bom inventei uma classe um pouco estranha, mas vai servir para o exemplo
.
public class Calculos
{
public int SomarDoisValores(int valor1, int valor2)
{
return valor1 + valor2;
}
public int SomarTresValores(int valor1, int valor2, int valor3)
{
return valor1 + valor2 + valor3;
}
public double SomarDoisValores(double valor1, double valor2)
{
return valor1 + valor2;
}
public double SomarTresValores(double valor1, double valor2, double valor3)
{
return valor1 + valor2 + valor3;
}
}
A idéia é colocar um breakpoint para cada método, e “agrupar” por Labels. Depois vamos fazer pesquisa pelos Labels para ver como encontrar facilmente algum breakpoint.
Com os breakpoints marcados, podemos colocar os Labels clicando com o botão direito no marcador do breakpoint e escolhendo a opção Edit Labels.
Outra possibilidade é pela janela de Breakpoints, essa janela mostra a lista dos breakpoints, também clicando com o botão direito no item, e escolhendo a opção Edit Labels.
Quando clicamos em Edit Labels a janela abaixo é aberta. E nela conseguimos colocar uma valor para a Label ou escolher entre valores já colocados em outros breakpoints.
Agora na janela de breakpoints conseguimos visualizar o Label de cada um dos itens.
Os Labels ajudam a organizar os breakpoints, principalmente se a quantidade de breakpoints for grande, mas felizmente podemos fazer uma busca de breakpoints por Label, utilizando a opção Search da janela de Breakpoints.
Veja abaixo que procurei pelo termo double e é mostrado somente os breakpoints que o Label contem a palavra double.
Como disse anteriormente, um recurso simples, que ajuda muito na organização dos breakpoints.
Abraços.
Novidades na depuração de código no VS2010 – IntelliTrace
16/06/10
No primeiro artigo sobre debug com o Visual Studio 2010, mostrei como fixar itens de debug, colocar comentários e ver os valores anteriores dos objetos fixados mesmo sem executar o programar.
Hoje vou falar de outro recurso sensacional chamado IntelliTrace.
Eu gosto de comparar o IntelliTrace com a janela History do Photoshop, isso mesmo, Photoshop. Mesmo para quem não conhece ou nunca viu essa janela, a idéia dela é salvar tudo que o usuário faz, desenhar algo, apagar, mover de lugar, e facilmente podemos voltar o que estivermos fazendo no Photoshop clicando nos eventos gravados, o IntelliTrace faz o mesmo com o nosso debug, ele gera um histórico de tudo que acontece durante a execução do sistema, e conseguimos voltar a pontos específicos, recuperar valores, ver chamadas de eventos, e muito mais.
Antes de começar um pequeno detalhe, o IntelliTrace está disponível somente no Visual Studio 2010 Ultimate então infelizmente se não possui a versão Ultimate não terá acesso ao IntelliTrace.
Primeiramente vamos ver as opções de configuração do IntelliTrace, no menu Tools/Options agora temos novas opções de configuração do Visual Studio e o IntelliTrace tem configurações específicas.
Por padrão o primeiro RadioButton vem selecionado, ou seja o IntelliTrace só vai coletar informações sobre os eventos, e como podem ver na tela, não afeta o desempenho na hora do debug.
Eu marco o segundo RadioButton, onde além dos eventos ele coleta as chamadas realizadas também durante o debug, mas pode afetar um pouco o desempenho durante o debug, confesso que nunca tive problemas com desempenho utilizando o recurso.
Outro detalhe importante que marquei na imagem, é que o recurso de Edit and Continue que permite alterar um código com o programa executando e continuar o debug é desabilitado.
Outra opção de configuração interessante no IntelliTrace é escolher quais eventos ele vai analisar.
A quantidade de opções é enorme, não vou listar as sub-opções mas as opções principais que podemos selecionar são.
- ADO.NET
- ASP.NET
- Console
- Data Binding
- Enviroment Variables
- File
- Gesture
- Lazy Initialization
- Registry
- ServiceModel
- Threading
- Tracing
- User Prompt
- Workflow
- XML
Agora vamos começar a brincadeira de verdade, vamos imaginar o seguinte bloco de código, que é o mesmo do antigo anterior com alguns acréscimos.
class Program
{
static void Main(string[] args)
{
var cliente = new Cliente();
cliente.Nome = "Márcio";
cliente.Idade = 26;
cliente.DescobrirMetadeDaIdade();
cliente.Nome = "Márcio Fábio Althmann";
cliente.Idade = new Random().Next(1, 99);
cliente.Idade = new Random().Next(1, 50) / 3;
}
}
class Cliente
{
public string Nome { get; set; }
public int Idade { get; set; }
public int MetadeIdade { get; set; }
public void DescobrirMetadeDaIdade()
{
if (Idade <= 0)
return;
MetadeIdade = Idade/2;
}
}
O código acima é simples, mas as duas últimas linhas onde utilizamos um Random para obter a idade é onde veremos como o IntelliTrace é interessante, quando estamos depurando algo no Visual Studio conseguimos sem problemas clicar na seta amarela que indica em qual linha estamos no momento, e arrastar a mesma para cima, e voltar o debug, mas no caso do Random isso não vai ajudar, por que quando passarmos novamente pela linha o Random será executado novamente.
Com o IntelliTrace poderemos voltar até as linhas do Random que o valor gravado não será trocado, afinal ele tem um “histórico” da execução.
Para utilizar o IntelliTrace é simples, colocamos um breakpoint e executamos o programa, quando a execução parar no breakpoint veremos algumas mudanças no Visual Studio. A primeira mudança é que ao lado da barra esquerda onde fica a marcação do breakpoint, uma nova barra é criada com botões do IntelliTrace, onde poderemos avançar e voltar os eventos ou chamadas registrados pelo IntelliTrace.
O Visual Studio também ganha uma janela nova também chamada IntelliTrace veja abaixo a janela mostrando o histórico de eventos da depuração, que é a mais simples, mas com ela também conseguimos “voltar no tempo” no nosso aplicativo (emprestei do Spoky esse termo
).
Nessa mesma janela podemos clicar no item Switch to Calls View que mostra de uma forma detalhado o que aconteceu com o aplicativo.
E conforme vamos navegando na lista de chamadas da janela, no editor de código o breakpoint volta ou avança na linha informada no histórico. Lembrando que poderemos voltar para a linha do Random e o valor não será modificado.
Eu iria gravar um pequeno vídeo mostrando o IntelliTrace funcionando, mas como o Spoky fez um vídeo sobre o assunto para a Copa Microsoft, clique aqui e veja o IntelliTrace funcionando, e se preparem para rir muito durante o vídeo, ficou muito bom
.
Abraços e até o próximo post.




