Supondo a seguinte hierarquia de herança hipotética:
public interface IA
{
int ID { get; set; }
}
public interface IB : IA
{
string Name { get; set; }
}
Usando reflexão e fazendo a seguinte chamada:
typeof(IB).GetProperties(BindingFlags.Public | BindingFlags.Instance)
só produzirá as propriedades da interface IB
, que é " Name
".
Se fizéssemos um teste semelhante no código a seguir,
public abstract class A
{
public int ID { get; set; }
}
public class B : A
{
public string Name { get; set; }
}
a chamada typeof(B).GetProperties(BindingFlags.Public | BindingFlags.Instance)
retornará uma matriz de PropertyInfo
objetos para " ID
" e " Name
".
Existe uma maneira fácil de encontrar todas as propriedades na hierarquia de herança para interfaces como no primeiro exemplo?
c#
.net
reflection
sduplooy
fonte
fonte
Stack<Type>
vez de umQueue<>
. Com uma pilha, a ancestralidade mantém uma ordem tal queinterface IFoo : IBar, IBaz
ondeIBar : IBubble
e 'IBaz: IFlubber, the order of reflection becomes:
IBar,
IBubble,
IBaz,
IFlubber,
IFoo`.GetProperties
. Você usaGetInterfaces
em seu tipo inicial que retornará a lista achatada de todas as interfaces e simplesmente faráGetProperties
em cada interface. Não há necessidade de recursão. Não há herança ou tipos de base nas interfaces.Type.GetInterfaces
retorna a hierarquia achatada, portanto, não há necessidade de uma descida recursiva.Todo o método pode ser escrito de forma muito mais concisa usando LINQ:
fonte
GetValue
o recuperadoPropertyInfo
, passando sua instância (cujo valor de propriedade obter) como parâmetro. Exemplo:var list = new[] { 'a', 'b', 'c' }; var count = typeof(IList).GetPublicProperties().First(i => i.Name == "Count").GetValue(list);
← retornará 3, emboraCount
seja definido emICollection
, nãoIList
.GetInterfaces
não é necessário setype
for uma classe, porque a classe concreta DEVE implementar todas as propriedades que são definidas em todas as interfaces na cadeia de herança. O usoGetInterfaces
nesse cenário resultaria na duplicação de TODAS as propriedades.Hierarquias de interface são uma dor - elas realmente não "herdam" como tal, já que você pode ter vários "pais" (por falta de um termo melhor).
"Achatar" (mais uma vez, não é exatamente o termo certo) a hierarquia pode envolver a verificação de todas as interfaces que a interface implementa e o trabalho a partir delas ...
fonte
Exatamente o mesmo problema tem uma solução alternativa descrita aqui .
FlattenHierarchy não funciona btw. (apenas no vars. estático diz isso no intellisense)
Gambiarra. Cuidado com as duplicatas.
fonte
Respondendo a @douglas e @ user3524983, o seguinte deve responder à pergunta do OP:
ou, para uma propriedade individual:
OK da próxima vez, vou depurá-lo antes de postar em vez de depois :-)
fonte
isso funcionou bem e concisa para mim em um fichário de modelo MVC personalizado. Deve ser capaz de extrapolar para qualquer cenário de reflexão. Ainda fede que seja muito passado
fonte