Brincando Com LINQ: Obtendo As Implementações De Propriedades De Interfaces

Hoje, o meu amigo Nuno estava a escrever algum código para obter as PropertyInfos da implementação de uma interface por parte de classe.

Dada este interface:

public interface ISomeInterface { int IntProperty { get; set; } string StringProperty { get; } void Method(); }

e esta classe:

public class SomeClass : ISomeInterface
{
    int ISomeInterface.IntProperty { get; set; }
    public int IntProperty { get; private set; }
    public string StringProperty { get; private set; }
    public void Method() { }
}

o Nuno queria obter:

  • Int32 ISomeInterface.IntProperty
  • System.String StringProperty

O código é relativamente simples. Primeiro é necessário obter os mapeamentos da interface:

typeof(SomeClass).GetInterfaceMap(typeof(ISomeInterface)).TargetMethods

e filtrar por PropertyInfos para as quais o MethodInfo é parte da sua implementação (implementa o método get ou o método set).

Algo como isto:

public static bool Implements(this MethodInfo methodInfo, PropertyInfo propertyInfo)
{
    return (propertyInfo.GetGetMethod(true) == methodInfo) || (propertyInfo.GetSetMethod(true) == methodInfo);
}

Mas o que me chamou a atenção foi que, com os  métodos de extensão acima, posso usar LINQ para obter as desejadas PropertyInfos.

Algo assim:

public static IEnumerable<PropertyInfo> GetInterfacePropertyImplementation(Type implementer, Type implemented)
{
    return (from propertyInfo in implementer.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).AsEnumerable()
            from methodInfo in implementer.GetInterfaceMap(implemented).TargetMethods.AsEnumerable()
            where methodInfo.Implements(propertyInfo)
            select propertyInfo).Distinct();
}

Para a classe e interface do exemplo, usar o método acimo seria algo como:

var q = GetInterfacePropertyImplementation(typeof(SomeClass), typeof(ISomeInterface));

foreach (var p in q)
{
    Console.WriteLine(p);
}

O que produzirá o seguinte resultado:

Int32 ISomeInterface.IntProperty
System.String StringProperty

ACTUALIZADO: A implementação anterior era demasiado complexa e baseada em strings. Obrigado, Nuno.

Published 27-1-2010 2:32 por Paulo Morgado

Leave a Comment

(requerido) 
(requerido) 
 
(opcional)
(requerido) 
If you can't read this number refresh your screen
Enter the numbers above: