Como posso encontrar todos os campos públicos de um objeto em C #?
Pergunta
Eu estou construindo um método para tomar um ArrayList (presumivelmente cheio de objetos) e, em seguida, listar todos os campos (e seus valores) para cada objeto no ArrayList.
Atualmente o meu código é a seguinte:
public static void ListArrayListMembers(ArrayList list)
{
foreach (Object obj in list)
{
Type type = obj.GetType();
string field = type.GetFields().ToString();
Console.WriteLine(field);
}
}
É claro, eu entendo a questão imediata com este código: se ele trabalhou ele só iria imprimir um campo por objeto no ArrayList. Vou consertar isso mais tarde -. Agora eu sou apenas curioso como para obter todos os campos públicos associados a um objeto
Solução
foreach (Object obj in list) {
Type type = obj.GetType();
foreach (var f in type.GetFields().Where(f => f.IsPublic)) {
Console.WriteLine(
String.Format("Name: {0} Value: {1}", f.Name, f.GetValue(obj));
}
}
Note que este código requer o .NET 3.5 para o trabalho; -)
Outras dicas
Você pode obter todos os objetos Campos declarou diretamente na classe com os BindingFlags:
GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
e todos os objetos campos, incluindo herdada com:
GetFields(BindingFlags.Public | BindingFlags.Instance)
public static void ListArrayListMembers(ArrayList list)
{
foreach (Object obj in list)
{
Type type = obj.GetType();
Console.WriteLine("{0} -- ", type.Name);
Console.WriteLine(" Properties: ");
foreach (PropertyInfo prop in type.GetProperties())
{
Console.WriteLine("\t{0} {1} = {2}", prop.PropertyType.Name,
prop.Name, prop.GetValue(obj, null));
}
Console.WriteLine(" Fields: ");
foreach (FieldInfo field in type.GetFields())
{
Console.WriteLine("\t{0} {1} = {2}", field.FieldType.Name,
field.Name, field.GetValue(obj));
}
}
}
Eu gostaria de mencionar que procura IsPublic nos campos não é necessário como type.GetFields () como definido pelo MSDN estados:
Valor de retorno - Tipo: System.Reflection.FieldInfo []
Uma matriz de FieldInfo objetos que representam todos os campos públicos definidos para o atual Type.
Claro, outra pergunta seria "por que você tem campos públicos?" - Propriedades de ser preferível. Como uma abstração, nota que a reflexão não é a única opção:., Também é possível para um tipo para expor suas propriedades on-the-fly em tempo de execução (como como um DataTable
untyped / DataView
expõe colunas como propriedades)
Para apoiar este (além de apoiar objetos simples), você usaria TypeDescriptor
:
foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
{
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
}
Isso também permite inúmeras opções de extensibilidade - por exemplo, muito acelerar reflexão (sem alterar qualquer código).
static void ListArrayListMembers(ArrayList list)
{
foreach (object obj in list)
{
Type type = obj.GetType();
foreach (FieldInfo field in type.GetFields(BindingFlags.Public))
{
Console.WriteLine(field.Name + " = " + field.GetValue(obj).ToString());
}
}
}