IEqualityComparer facilitado

2/26/2010 2:16:00 AM By Felipe Pessoto

Quando usamos o Linq temos alguns extension methods muito úteis como Distinct e Except. Porém para fazer uma comparação customizada é necessário criar uma classe que herde de IEqualityComparer<T> e passar uma instancia como parâmetro, o que considero muito sujo, principalmente se cada comparar for de um jeito.

Encontrei uma solução no blog do Brendan Enrick, porém pra mim não funcionou. não sei se fiz algo errado, mas o LINQ sempre chamava primeiro o GetHashCode, que se não fosse igual já retornava false sem nem passar pelo Equals. Alterei para aceitar uma Func que será usada no GetHashCode também, assim só precisamos dessa classe e podemos fazer a chamada da seguinte forma:

List<MyObject> x = myCollection.Except(otherCollection, (x, y) => x.Codigo == y.Codigo, z => z.Codigo).ToList();

Onde "(x, y) => x.Codigo == y.Codigo" é nossa comparação, e  z => z.Codigo o GetHashCode. Assim usamos o Except ou Distinct da mesma maneira que o Where, First, Any, etc

Código:

public static class InterfaceEnumerableExtension
{
     public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first,
     IEnumerable<TSource> second, Func<TSource, TSource, bool> comparer, Func<TSource, int> hashFunction)
     {
         return first.Except(second, new LambdaComparer<TSource>(comparer, hashFunction));
     }
 }

public class LambdaComparer<T> : IEqualityComparer<T>
{
     private readonly Func<T, T, bool> lambdaComparer;
     private readonly Func<T, int> lambdaHash;

     public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
     {
         if (lambdaComparer == null)
             throw new ArgumentNullException("lambdaComparer");
         if (lambdaHash == null)
             throw new ArgumentNullException("lambdaHash");

         this.lambdaComparer = lambdaComparer;
         this.lambdaHash = lambdaHash;
     }

     public bool Equals(T x, T y)
     {
         return lambdaComparer(x, y);
     }

     public int GetHashCode(T obj)
     {
         return lambdaHash(obj);
     }
}

 

Podcast sobre Qualidade de Software

2/11/2010 2:01:00 PM By Felipe Pessoto

Estou acompanhando os podcasts do .Net Architects e tenho gostado muito dos debates.

Esta semana saiu mais um, sobre Qualidade de Software:

"Neste episódio do .Net Architects Podcast Alexandre Valente, Giovanni Bassi e Denis Ferrari falam sobre qualidade de software, esse episódio nasceu de uma discussão iniciada pelo Alexandre Valente no .Net Architects.

Alguns dos temas abordados foram:
O que é qualidade de software.
Como medir qualidade de Software.
Responsabilidades do gerente de TI.
Treinamento x Qualidade."

Download (13,06MB)

.Net Architects Podcast

ASP.NET MVC 2 Release Candidate 2

2/6/2010 3:41:00 PM By Felipe Pessoto

Foi lançado um novo release candidate do ASP.NET MVC 2. Esta versão será importante pois traz algumas modificações importantes, principalmente nas validações.

Antes se você recebia um tipo "Comentario" no seu Action Method, o Model Binder do ASP.NET MVC somente validava os campos que vieram no POST, por exemplo um campo obrigatório que viesse vazio. O problema era que um usuário mal intencionado poderia alterar o seu html do lado cliente e fazer um under-post, evitando que a validação pegasse o erro. Este era um comportamento intencional, pois os desenvolvedores do ASP.NET MVC queriam permitir que fossem criadas Views parciais sem a necessidade de se ter outra classe específica para ela.

Alguns desenvolvedores do MVC ainda alertam que mesmo assim o problema não está totalmente resolvido, pois a Validação não é um sistema de segurança, e sim somente para validar. Não vai previnir que o usuário faça por exemplo um over-post, por exemplo mudando a flag do comentario para Aprovado. Por isso a importância de ser usar uma white/black-list em todos os binds, principalmente as white-lists que são mais seguras.

 Além disso os Input Helpers fortemente tipados agora suportam indices, algumas melhorias de usabilidade nos validators, o jQuery foi atualizado pro 1.4.1 e foram feitas melhorias de performance.