Existem vários cenários a serem considerados. Primeiro de tudo, você precisa verificar o tipo do seu objeto. Você pode simplesmente chamar GetType () para isso. Se o tipo não implementar IDynamicMetaObjectProvider, você poderá usar a mesma reflexão de qualquer outro objeto. Algo como:
var propertyInfo = test.GetType().GetProperties();
No entanto, para implementações IDynamicMetaObjectProvider, a reflexão simples não funciona. Basicamente, você precisa saber mais sobre esse objeto. Se for ExpandoObject (que é uma das implementações IDynamicMetaObjectProvider), você poderá usar a resposta fornecida por itowlson. ExpandoObject armazena suas propriedades em um dicionário e você pode simplesmente converter seu objeto dinâmico em um dicionário.
Se for DynamicObject (outra implementação de IDynamicMetaObjectProvider), será necessário usar quaisquer métodos que este DynamicObject exponha. O DynamicObject não é necessário para "armazenar" realmente sua lista de propriedades em qualquer lugar. Por exemplo, pode ser algo como isto (estou reutilizando um exemplo da minha postagem no blog ):
public class SampleObject : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = binder.Name;
return true;
}
}
Nesse caso, sempre que você tentar acessar uma propriedade (com qualquer nome), o objeto simplesmente retornará o nome da propriedade como uma sequência.
dynamic obj = new SampleObject();
Console.WriteLine(obj.SampleProperty);
//Prints "SampleProperty".
Portanto, você não tem nada para refletir - esse objeto não possui propriedades e, ao mesmo tempo, todos os nomes de propriedades válidos funcionarão.
Eu diria que para implementações IDynamicMetaObjectProvider, você precisa filtrar implementações conhecidas, onde pode obter uma lista de propriedades, como ExpandoObject, e ignorar (ou lançar uma exceção) para o resto.