Analisando a exceção ContractException

by Israel Aece 15. August 2010 21:17

A partir de agora, durante a escrita do nosso código, podemos recorrer ao Code Contracts, que é uma biblioteca que está sendo desenvolvida pela Microsoft, e que permite trabalhar com condições e garantir com que elas sejam atendidas durante a execução ou até mesmo de forma estática. Caso alguma das regras impostas seja violada, uma exceção será disparada, caracterizando um bug no sistema que consome este componente. O uso desse novo recurso tende a diminuir consideravelmente o uso do código if-then-throw.

A exceção que é disparada é do tipo ContractException e, propositalmente, ela foi criada como internal. Isso evita que se crie tratadores de erro que capture este tipo de exceção, e com isso burle o processo de verificação que é realizado por essa biblioteca. A aplicação que consome a classe deve se preocupar apenas em capturar exceções tradicionais (ArgumentNullException, IndexOutOfRangeException, etc.), pois enquanto houver exceções do tipo ContractException sendo disparadas, provavelmente o consumidor não está passando as informações da forma correta.

Há alguns momentos em que gostaríamos de mudar este comportamento, como por exemplo, eliminar essa validação durante a escrita de algum teste (isso envolve outra discussão, que é TDD com DbC). Para exemplificar, considere o código abaixo, que possui uma condição pré (Requires) e outra pós (Ensures), que recorre ao Code Contracts para validar e garantir que as informações são passadas da forma correta para o método Creditar e também garante o estado da classe ContaBancaria, após a execução deste mesmo método.

public class ContaBancaria
{
    public decimal Saldo { get; private set; }

    public ContaBancaria(decimal saldo)
    {
        this.Saldo = saldo;
    }

    public void Creditar(decimal quantia)
    {
        Contract.Requires(quantia > 0, "A quantia para deposito deve ser maior que 0");
        Contract.Ensures(Contract.OldValue(this.Saldo) + quantia == this.Saldo);

        this.Saldo += quantia;
    }
}

Se criarmos um código para consumir essa classe e, consequentemente, efetuar um crédito com valor negativo, teremos uma exceção do tipo ContractException. Para contornar esse comportamento, podemos recorrer ao evento estático ContractFailed da classe Contract. Esse evento define o argumento do tipo ContractFailedEventArgs, que expõe alguns membros interessantes, e alguns deles estão listados abaixo:

  • Condition: Uma string com a condição que não foi atentida.
  • FailureKind: Uma das opções exposta pelo enumerador ContractFailureKind, indicando se é uma condição pré, pós ou invariante.
  • Message: Uma string que representa a mensagem que descreve o problema.
  • OriginalException: Retorna a instância da exceção que causou o evento, que é utilizado quando você utiliza métodos que, por questões de compatibilidade, dispara exceções diferentes de ContractException.
  • SetHandled: Método que quando invoca, suprime o disparo da exceção que violou o contrato.
  • SetUnwind: Ao contrário do método anterior, quando invocado ele dispara a exceção ContractException depois que o tratador do evento ContractFailed é encerrado.

Com os membros que vimos acima, podemos agora ter acesso ao tipo do problema que ocorreu, e ainda conseguir burlar o problema de verificação que é realizado pelo Code Contracts. Abaixo temos um exemplo de como podemos proceder para fazer isso funcionar, ou seja, invocando o método SetHandled para que erros que violam o contrato não sejam mais entregues para o código consumidor:

static void Main(string[] args)
{
    Contract.ContractFailed += (sender, args) =>
    {
        Console.WriteLine("{0} - {1}", args.FailureKind, args.Condition);
        args.SetHandled();
    };

    new ContaBancaria(1000).Creditar(-100);
}

Tags:

C#

Omitindo tipos genéricos durante a construção

by Israel Aece 10. August 2010 22:38

Os Generics trouxeram um grande poder às linguagens .NET. O tipos genéricos podem ser utilizados por toda a classe onde ele está sendo criado e, consequentemente, podemos utilizar em seus construtores. O maior problema da criação de objetos que exigem um parâmetro genérico, é a necessidade de especificarmos esses tipos durante a sua construção, ou seja, o construtor não é capaz de inferir os tipos, o que torna o código um pouco ilegível. Para exemplificar, considere o seguinte código:

public class ProxyManager<TChannel, TBinding>
{
    private TChannel _channel;
    private TBinding _binding;

    public ProxyManager(TChannel channel, TBinding binding)
    {
        this._channel = channel;
        this._binding = binding;
    }

    //Outros Membros
}

Durante a sua criação, é necessário especificarmos os tipos genéricos para depois conseguir parametrizar o construtor com os valores efetivos. Se repararmos o código abaixo, note que não podemos omitir o que está entre os caracteres < e >, mesmo que construtores são uma espécie de método, eles não possibilitam a omissão dos mesmos, assim como acontece nos métodos genéricos.

var manager = 
    new ProxyManager<ServicoDeUsuariosClient, NetTcpBinding>(
        new ServicoDeUsuariosClient(), 
        new NetTcpBinding());

Para melhorar esse código e torná-lo mais simples de consumir a classe, podemos recorrer a criação de uma nova classe, que conterá um método estático que aceita exatamente os parâmetros genéricos exigidos pelo construtor da classe ProxyManager<TChannel, TBinding>, e o retorno será a própria classe criada, uma espécie de factory. O que acontece aqui é que todo o código burocrático acaba ficando dentro deste método.

public static class ProxyManager
{
    public static ProxyManager<TChannel, TBinding> Create<TChannel, TBinding>(TChannel channel, TBinding binding)
    {
        return new ProxyManager<TChannel, TBinding>(channel, binding);
    }
}

Com isso, a criação de um novo ProxyManager, se resume simplesmente ao código que vemos abaixo:

var manager = 
    new ProxyManager.Create(new ServicoDeUsuariosClient(), new NetTcpBinding());

Tags:

C#

Detectando mudanças em objetos

by Israel Aece 22. June 2010 12:14

Há uma porção de funcionalidades dentro do .NET Framework, que podemos incorporar em nossos tipos, para enriqucê-los ainda mais em nível de comportamento. Essas funcionalidades predefinidas, já trazem recursos extremamente interessantes, que com pouco de código extra que utilizamos para "rechear" os pontos customizados, poderemos poupar muitas e muitas linhas de código se fossemos fazer isso manualmente.

Entre as várias funcionalidades que existem e que já falei bastante por aqui, uma delas é a capacidade que temos de dectectar mudanças que acontecem no estado (propriedades) das nossas classes. Geralmente as classes possuem propriedades que podem ser alteradas durante a sua execução, sendo essa alteração realizada através do bloco Set da mesma, ou através de algum método que a manipula internamente.

Por algum motivo, se quisermos detectar que alguma mudança está acontecendo ou já aconteceu, podemos implementar nesta classe as interfaces INotifyPropertyChanging e INotifyPropertyChanged que estão debaixo do namespace System.ComponentModel. Cada uma delas é utilizada para interceptar momentos diferentes, ou seja, a primeira deve ser utilizada quando queremos ser notificados antes da mudança, enquanto a segunda deverá ser utilizada para notificar quando a mudança já aconteceu.

A primeira interface, INotifyPropertyChanging, fornece um único membro, que é o evento PropertyChanging. Já a segunda, INotifyPropertyChanged, disponibiliza um outro evento chamado PropertyChanged. Ambas interfaces podem ser implementadas em classes que você deseja monitorar as alterações que podem acontecer em suas respectivas propriedades. Com isso, podemos permitir aos consumidores desta classe, serem notificados antes e depois da mudança acontecer, podendo assim tomar alguma decisão em cima disso.

Como podemos notar no código abaixo, temos uma classe chamada Cliente, que por sua vez, contém apenas uma única propriedade chamada Nome. Para qualquer evento que você crie, o ideal é criar um método que encapsule a regra para a construção dos parâmetros e o disparo dele, para evitar redundâncias pelo código. Para isso, foram criados dois métodos auxiliares, onde cada um deles encapsula a chamada para o evento que ele gerencia. Note que a atribuição do valor ao membro interno da classe, somente se dá caso o valor que chega para ela seja diferente do qual ela possui, justamente porque não faz sentido notificar alguém que a propriedade foi mudada, mas que efetivamente não foi. É importante notar também que a alteração que será feita na propriedade está envolvida pela chamada dos eventos, ou seja, antes da alteração disparamos o evento PropertyChanging, e depois que a alteração foi realizada, disparamos o evento PropertyChanged.

public class Cliente : INotifyPropertyChanging, INotifyPropertyChanged
{
    private string _nome;

    public string Nome
    {
        get
        {
            return this._nome;
        }
        set
        {
            if (value != this._nome)
            {
                this.OnPropertyChanging("Nome");
                this._nome = value;
                this.OnPropertyChanged("Nome");
            }
        }
    }

    public event PropertyChangingEventHandler PropertyChanging;

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanging(string propertyName)
    {
        if (this.PropertyChanging != null)
            this.PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Com isso, ao construir um objeto do tipo Cliente, definimos a sua propriedade Nome como "Israel". Em seguida, nos vinculamos aos eventos PropertyChanging e PropertyChanged, para sermos notificados caso qualquer alteração aconteça nas propriedades deste objeto. Tudo o que estamos fazendo no código abaixo, é escrevendo na tela a notificação da alteração da propriedade Nome. Finalmente, quando alteramos a propriedade Nome de "Israel" para "Israel Aece", notamos que as mensagens de notificação aparecerão na tela.

Cliente c = new Cliente() { Nome = "Israel" };

c.PropertyChanging += 
    (sender, e) => Console.WriteLine("Alterando a propriedade '{0}'.", e.PropertyName);

c.PropertyChanged +=
    (sender, e) => Console.WriteLine("Propriedade '{0}' alterada.", e.PropertyName);

c.Nome = "Israel Aece";

Assim como existe essas interfaces que agregam às nossas classes, a possibilidade de serem monitoradas quando alguma mudança acontecer, também há uma nova interface chamada INotifyCollectionChanged (namespace System.Collections.Specialized), que como o nome sugere, permite adicionar à uma coleção, a possibilidade de monitoramento da mesma, onde seremos notificados quando ela for modificada, ou seja, quando elementos forem adicionados ou removidos. Essa interface fornece um único membro, que é o evento CollectionChanged.

Esse evento faz uso de um parâmetro do tipo NotifyCollectionChangedEventArgs, que expõe algumas propriedades interessantes, como por exemplo: Action, NewItems e OldItems. O primeiro deles, retorna uma das opções do enumerador NotifyCollectionChangedAction, dizendo qual foi a ação que aconteceu. Já a propriedade NewsItems, disponiliza um objeto do tipo IList, contendo os novos itens que foram adicionados, enquanto a propriedade OldItens, retorna o mesmo tipo da propriedade anterior, mas com os objetos que foram removidos da coleção.

Essa interface nos permite criar uma coleção que pode ser monitorada quando os elementos dela são manipulados. Felizmente, a Microsoft já adicionou uma coleção genérica chamada ObservableCollection<T>, que está debaixo do namespace System.Collections.ObjectModel, já implementada com essa funcionalidade.

É importante dizer que quando estamos falando no monitoramento de modificações em uma coleção, estamos atentos aos itens que ela armazena, se novos são inseridos, se outros são removidos, alterados, etc. Se uma propriedade de um objeto que está dentro dela for alterada, nada acontecerá à coleção. Como exemplo de uso, podemos visualizar o código abaixo, que cria uma instância desta coleção, definindo o tipo T como sendo Cliente. Antes de começarmos a manipular a coleção, vamos nos vincular ao evento CollectionChanged, para sermos notificados quando novos itens forem adicionados ou removidos.

static void Main(string[] args)
{
    ObservableCollection<Cliente> clientes = new ObservableCollection<Cliente>();
    clientes.CollectionChanged += ColecaoAlterada;

    clientes.Add(new Cliente() { Nome = "Israel" });
    clientes.Add(new Cliente() { Nome = "Claudia" });
    clientes.Add(new Cliente() { Nome = "Virginia" });
}

static void ColecaoAlterada(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
        VisualizarClientes("Cliente(s) Adicionado(s)", e.NewItems);

    if (e.Action == NotifyCollectionChangedAction.Remove)
        VisualizarClientes("Cliente(s) Removido(s)", e.OldItems);
}

static void VisualizarClientes(string titulo, IList itens)
{
    if (itens != null && itens.Count > 0)
    {
        Console.WriteLine(titulo);

        foreach (var item in itens)
            Console.WriteLine("\t{0}", item);
    }
}

Ao executar o código acima, o método ColecaoAlterada será disparado três vezes, sendo uma para cada novo cliente que está sendo adicionado à coleção. Apesar de não estar sendo utilizado aqui, a classe ObservableCollection<T> também implementa a interface INotifyPropertyChanged, que tem a finalidade de monitorar duas propriedades, sendo elas: Items e Count, que são as principais propriedades de qualquer coleção.

Observação: Inicialmente os tipos que vimos aqui para monitoramento de coleções, foram criados para atender ao Windows Presentation Foundation, e justamente por isso, também podem ser encontrados dentro do assembly WindowsBase.dll. A partir da versão 4.0 do .NET Framework, a Microsoft trouxe esses tipos para dentro do assembly System.dll, que nos permite utilizá-los por qualquer tipo de aplicação, sem a necessidade de referenciar diretamente um assembly de uma tecnologia específica.

Conclusão: Vimos no decorrer deste artigo como podemos incorporar em nossas classes a funcionalidade para detectar mudanças, recorrendo à recursos do próprio .NET Framework. Grande parte do que vimos neste artigo, serve como base para grandes funcionalidades que estão espalhados por toda a plataforma .NET, como é o caso do databinding do WPF, consumo de serviços WCF (Data Services), entre outros. A ideia aqui foi apresentar, de uma forma "crua", essas funcionalidades, para mais tarde abordar outros recursos expostos pelo .NET Framework que fazem uso disso, e que já assumirão o conhecimento que vimos aqui.

Tags: ,

.NET Framework | C#

Evento de Tecnologia em Hortolândia

by Israel Aece 25. May 2010 21:36

No próximo dia 01 de junho (terça-feira) acontecerá um evento na UNASP Hortolândia (Centro Universitário Adventista de São Paulo), na cidade de Hortolândia. Para quem é de Campinas e região, este evento acontecerá na sede da universidade, localizada na Rua Pr. Hugo Gegembauer, 265, Parque Hortolândia, à partir das 19:45. Eu palestrarei sobre o Visual Studio 2010 e o .NET Framework 4.0. É importante dizer que a palestra será de nível 100, que além de abordar superficialmente algumas das principais funcionalidades desta nova versão, falaremos um pouco também sobre algumas tecnologias que já existem e estão à disposição desde as versões anteriores. Abaixo temos a descrição da palestra:

Título: Visual Studio 2010 e .NET Framework 4.0
Palestrante: Israel Aece
Descritivo: Esta palestra tem a finalidade de exibir um “tour” sobre a plataforma .NET, e a principal ferramenta que utilizamos para desenvolver aplicações para ela, que é o Visual Studio. A ideia é demonstrar rapidamente a história e a evolução do .NET Framework até a versão 4.0, incluindo assuntos como as linguagens de programação (C# e VB.NET), acesso à dados e aplicações para internet (WebForms, MVC e Silverlight). Logo após, vamos analisar de forma superficial as novidades que estão sendo incluídas na IDE do Visual Studio 2010 e que dão suporte ao desenvolvimento de qualquer tipo de aplicação sobre a plataforma .NET.

Tags: , , ,

C# | Data | General | WCF

Community Launch em Campinas

by Israel Aece 15. March 2010 22:38

No próximo dia 20 de março acontecerá um evento chamado de Community Launch. Esse evento será espalhado por todo o Brasil, onde cada região criará o evento e abordará os principais produtos da Microsoft que estarão sendo lançados neste ano de 2010, a saber: Visual Studio 2010, Windows Server 2008 R2SQL Server 2008 R2.

Para quem é de Campinas e região, este evento acontecerá na Universidade UNIP, localizada no bairro Swift, à partir das 09:00 da manhã. Caso você não saiba exatamente onde ela está localizada, consulte este endereço para saber como chegar até lá. Entre as várias palestras, eu sou o responsável por falar sobre Visual Studio 2010 e .NET Framework 4.0. É importante dizer que a palestra será de nível 100, que além de abordar superficialmente algumas das principais funcionalidades desta nova versão, falaremos um pouco também sobre algumas tecnologias que já existem e estão à disposição desde as versões anteriores. Abaixo temos a descrição da palestra:

Título: Visual Studio 2010 e .NET Framework 4.0
Palestrante: Israel Aece
Descritivo: Esta palestra tem a finalidade de exibir um “tour” sobre a plataforma .NET, e a principal ferramenta que utilizamos para desenvolver aplicações para ela, que é o Visual Studio. A ideia é demonstrar rapidamente a história e a evolução do .NET Framework até a versão 4.0, incluindo assuntos como as linguagens de programação (C# e VB.NET), acesso à dados e aplicações para internet (WebForms, MVC e Silverlight). Logo após, vamos analisar de forma superficial as novidades que estão sendo incluídas na IDE do Visual Studio 2010 e que dão suporte ao desenvolvimento de qualquer tipo de aplicação sobre a plataforma .NET.

IMPORTANTE: Apesar do evento ser gratuito, para poder participar é necessário efetuar o cadastro aqui.

Tags: , , ,

.NET Framework | C# | Data | General | VB.NET

Adicionando Membros em Tempo de Execução

by Israel Aece 4. October 2009 20:47

Como sabemos, o C# 4.0 (que virá junto com o Visual Studio .NET 2010) já trará alguns aspectos de linguagens dinâmicas, que permitem a avaliação/checagem de um membro somente em tempo de execução. Para suportar esta funcionalidade, um novo "tipo" foi criado, conhecido como "dynamic". Ao declarar uma variável do tipo "dynamic", a checagem de existência de um determinado membro não acontecerá estaticamente, ou seja, independentemente se ele exista ou não, você somente saberá isso em tempo de execução.

Com este tipo especial, você somente conseguirá acessar os membros que, eventualmente, já existam. Mas e como você pode proceder, se quiser construir um tipo dinamicamente? É aqui que entra em cena a classe ExpandoObject (namespace System.Dynamic). Ao instanciar essa classe, você poderá criar tipos dinamicamente, definindo novas propriedades e métodos para este tipo. Para que isso funcione adequadamente, você precisará atribuir a instância desta classe à uma variável do tipo "dynamic", caso contrário, como vimos acima, a checagem será efetuada durante a compilação, o que não permitirá a compilação. O código abaixo ilustra a utilização desta nova classe:

dynamic obj = new ExpandoObject();
obj.Nome = "Israel";
obj.Endereco = new ExpandoObject();
obj.Endereco.Cidade = "Valinhos";
obj.AlgumMetodo = new Action<string>(s => Console.WriteLine(s));

Console.WriteLine(obj.Endereco.Cidade);
obj.AlgumMetodo("Teste");

Como podemos notar, instanciamos a classe ExpandoObject para uma variável definida como dinâmica. Depois disso, quando queremos criar "sub-tipos", basta instanciar uma nova classe ExpandoObject para ele, e seguir criando os novos membros a partir dali. Métodos também podem ser criados, e você pode recorrer a algum delegate já existente para definir a ação a ser executada quando ele for invocado.

Na verdade, esses membros não são incluídos dentro da classe ExpandoObject. A medida que você vai criando estes membros, ele irá armazenando em um dicionário, e quando requisitado, extrai e o executa. Essa funcionalidade é disponibilizada através da Interface IDynamicMetaObjectProvider. Acredito que a performance deva ser mais lenta do que o binding estático, mas é um preço que se deve pagar quando quiser interoperar com linguagens dinâmicas que, além da interoperabilidade com o mundo COM é, ao meu ver, os principais cenários para códigos deste tipo.

Tags:

.NET Framework | C#

Método Zip

by Israel Aece 20. September 2009 17:29

Um novo método (de extensão) foi adicionado à classe Enumerable na versão 4.0 do .NET, chamado de Zip. Dado duas coleções/arrays, esse método tem a finalidade de aplicar uma espécie de "zíper" entre eles, ou seja, agrupando os elementos correntes de cada coleção, onde o resultado é a combinação entre esses dois elementos. Para exemplificar, considere os dois arrays de inteiros:

int[] pares = new int[] { 0, 2, 4, 6, 8 };
int[] impares = new int[] { 1, 3, 5, 7, 9 };

foreach
(var item in impares.Zip(pares, (i, p) => string.Format("{0}, {1}, ", p, i)))
    Console.Write(item);

O resultado ficará: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. O processamento se encerra quando não for encontrado um elemento "correspondente" na outra coleção.

Tags: ,

.NET Framework | C#

MultiMethods

by Israel Aece 1. May 2009 20:03

É muito comum criarmos métodos em nossas classes que possuam “versões” diferentes. Por “versão”, entenda como overload ou sobrecarga do método. Isso quer dizer que podemos ter um método com o mesmo nome, mas que possuem quantidade ou tipos diferentes.

Em linguagens como o C# e o VB.NET, a resolução de qual dos overloads será invocado é feita em tempo de compilação, baseando no tipo que está sendo passado para o método, o compilador determinará qual das versões invocar. Suponhamos que temos a seguinte estrutura de classes:

public class Pessoa
{
    public string Nome;
}

public class PessoaJuridica : Pessoa
{
    public string CNPJ;
}

public class PessoaFisica : Pessoa
{
    public string CPF;
}

Agora, temos uma classe que tem a finalidade de gerenciar instâncias da classe Pessoa. Essa classe possui dois overloads, onde cada um deles espera uma instância concreta da classe Pessoa:

public class GestorDePessoas
{
    public void AdicionarPessoa(PessoaFisica pf)
    {
        Console.WriteLine("PF");
    }

    public void AdicionarPessoa(PessoaJuridica pj)
    {
        Console.WriteLine("PJ");
    }
}

Nossa aplicação trabalhará de forma independente de qual tipo de Pessoa esteja utilizando. Haverá um método chamado ConstruirPessoa que, dado o nome e o número do documento, retornará uma instância da classe PessoaFisica ou PessoaJuridica que, no nosso caso, deveremos passá-la para a classe GestorDePessoas. Se traduzirmos este parágrafo para código, então teríamos algo como:

Pessoa p = ConstruirPessoa(“Israel Aece”, “123456789”);
GestorDePessoas gp = new GestorDePessoas();
gp.AdicionarPessoa(p);

Se tentarmos compilar, receberemos um erro avisando que não foi possível encontrar um método com essa assinatura. As duas versões do método AdicionarPessoa esperam instâncias das classes concretas (PessoaFisica e PessoaJuridica). Mesmo que “p” armazene internamente a instância de uma classe concreta, ele não conseguirá determinar qual dos métodos invocar, pois somente saberemos o que “p” representa durante a execução da aplicação.

MultiMethods é um conceito que existe para escolher qual dos métodos invocar em tempo de execução, ao contrário do que acontece com o overloading, que fará essa escolha estaticamente, ainda em tempo de compilação. Há várias implementações de MultiMethods para .NET, e uma delas é o MultiMethods.NET. Com essa library, podemos criar apenas uma versão pública do método, que por sua vez, receberá a versão mais básica do tipo, que no nosso caso é a classe Pessoa. Internamente, a library determinará qual dos overloads invocar de acordo com o tipo que está sendo passado. O código abaixo ilustra a classe GestorDePessoas ligeiramente alterada, utilizando a library em questão:

public class GestorDePessoas
{
    private MultiMethod.Action<Pessoa> _adicionar;

    public GestorDePessoas()
    {
        this._adicionar = Dispatcher.Action<Pessoa>(this.AdicionarPessoa);
    }

    public void AdicionarPessoa(Pessoa p)
    {
        this._adicionar(p);
    }

    protected virtual void AdicionarPessoa(PessoaFisica pf)
    {
        Console.WriteLine("PF");
    }

    protected virtual void AdicionarPessoa(PessoaJuridica pj)
    {
        Console.WriteLine("PJ");
    }
}

O código de consumo desta classe que antes não funcionava, passa a funcionar, e em tempo de execução, o método AdicionarPessoa será invocado de acordo com o tipo retornado pelo método ConstruirPessoa. Publicamente temos apenas o método AdicionarPessoa que aceita o tipo base, e dentro dele, utiliza o delegate fornecido pela library para efetuar a escolha do método.

É importante dizer que estas libraries de MultiMethods recorrem a Reflection para efetuar todo o trabalho, e como sabemos, isso possui um overhead extra. Se de um lado ganhamos em flexibilidade, do outro perdemos em performance. Já com o .NET 4.0, o “tipo” dynamic evitará o uso dos MultiMethods. Esta palavra chave informará ao compilador que o método somente deverá ser conhecido em tempo de compilação, também se baseando nos tipos que forem passados à ele.

Ao contrário de grande parte dos tipos do .NET, a keyword dynamic não esta mapeada para algo como System.Dynamic; ao detectar uma variável definida com esta keyword, o compilador efetivamente criará uma variável do tipo System.Object mas, internamente, deverá recorrer à alguma API de DLR para invocar o membro, que talvez possa ser mais performático que Reflection.

Tags: , ,

C# | VB.NET

Powered by BlogEngine.NET 1.5.0.0
Theme by Mads Kristensen

Sobre

Meu nome é Israel Aece e sou especialista em tecnologias de desenvolvimento Microsoft, atuando como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. [ Mais ]

Twitter

Host