Covariância no .NET Framework 4
Apr 22
Artigos, Código .net framework 4, covariancia, generics 1 Comment
Galera,
Vou falar aqui um pouco sobre covariância, que é um recurso do .Net Framework 4, e como este recurso salvou o engine de validação do LiteFx.
Primeiramente irei explicar uma coisa antes que alguem pergunte porque diabos eu resolvi fazer um engine de validação.
Eu estava em casa e pensei em escrever um engine de validação, dai o código começou a fluir na minha cabeça e não consegui me controlar.
Em uma tarde estava pronto o esboço inicial e funcional. Como eu o fiz completamente desacoplado (se você usar o LiteFx não será obrigado a usar o engine de validação) resolvi deixa-lo no framework.
O Engine está muito legal e na versão 1.5 do LiteFx teremos uma integração com client validation, ou seja, vai ficar muito mais legal do que já esta.
Ah!!! E o engine já funciona junto com DataAnnotations sem nenhum conflito.
As validações do LiteFx são fluentes (artigo sobre fluent interface do martin fowler), e que na minha opinião ficam muito mais elegantes do que usar DataAnnotations, e no meu ponto de vista o código de validação de uma Entidade deve ficar junto do código da Entidade.
Agora vamos ao que interessa. Vamos falar sobre covariância.
Escrevi um código que testa o conceito de convariancia que vamos discutir daqui a pouco.
Vejamos o seguinte cenário, você tem um classe com o nome Base e outra classe com o nome Derived. A classe Derived herda da classe Base.
Pense bem, se você tiver uma bases do tipo IEnumarable
Se você estiver usando o .Net Framework 3.5 não irá funcionar, mas se você estiver usando o .Net 4.0 irá, tudo isto graças a convariancia.
A covariância funciona somente para interface e delegate.
O IEnumerable
public interface IEnumerable<T> { ... }
Já no .Net 4.0 é assim:
public interface IEnumerable<out T> { ... }
A diferença esta na palavra chave out. É esta palavra chave que usamos para dizer que nossa interface/delegate é covariante.
Agora vamos entender a covariância na prática?
Ná linha 41 do código acima temos a classe Base, que é a nossa classe base.
Ná linha 43 temos a nossa classe derivada de Base, a classe Derived.
Ná linha 45 temos a nossa interface ICovariant, notem que esta interface faz uso da keyword out.
Já na linha 47 temos a classe Covariant que implementa a interface ICovariant.
Agora vamos analisar os testes da covariância.
Ná linha 10 esta definido um método que irá testar a covariância. Neste método eu crio uma variavél do tipo ICovariante
Após isto defino uma segunda variável do tipo ICovariante
Logo depois realizo um cast da variável derived para @base (não é necessario realizar o cast, fiz isto somente para criar um “suspense” no teste, hehe), e consequentemente verifico se @base não é nula.
Como nosso tipo é covariante o teste irá passar (sério, eu já o executei).
Já na linha 49 temos a interface INotCovariant que não faz uso da keyword out, e na linha 51 temos a classe NotCovariant que implementa a interface INotCovariant.
Na linha 27 temos o teste que faz a mesma coisa que o teste da covariância, mas este teste usa os tipos não covariantes, sendo assim este método de teste espera uma exceção do tipo InvalidCastException, que ocorrerá na linha 34, quando tetarmos converter o nosso tipo não covariante.
Poxa, legal Douglas, mas aonde isto te ajudou no LiteFx?
Com este recurso pude fazer com que o engine de validação do LiteFx suporta-se herança. Agora como eu fiz isto fica para outro post, mas se você estiver muito curioso pode ver o código fonte do LiteFx em http://litefx.codeplex.com.
Valeu! Até a próxima!








