Domanda

Sto costruendo un metodo per includere un ArrayList (presumibilmente pieno di oggetti) e quindi elencare tutti i campi (e i loro valori) per ciascun oggetto nell'ArrayList.

Attualmente il mio codice è il seguente:

public static void ListArrayListMembers(ArrayList list)
    {
        foreach (Object obj in list)
        {
            Type type = obj.GetType();
            string field = type.GetFields().ToString();
            Console.WriteLine(field);

        }
    }

Ovviamente, capisco il problema immediato con questo codice: se funzionasse, stampa solo un campo per oggetto nell'ArrayList. Risolverò più tardi - in questo momento sono solo curioso di sapere come ottenere tutti i campi pubblici associati a un oggetto.

È stato utile?

Soluzione

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));
    }                           
}

Nota che questo codice richiede .NET 3.5 per funzionare ;-)

Altri suggerimenti

Puoi ottenere tutti i campi oggetto dichiarati direttamente nella classe con BindingFlags:

GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)

e tutti i campi oggetto inclusi quelli ereditati con:

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));
        }
    }
}

Vorrei menzionare che cercare IsPublic nei campi non è necessario come type.GetFields () come definito da MSDN afferma:

Valore restituito - Digitare: System.Reflection.FieldInfo []

Un array di oggetti FieldInfo che rappresentano tutti i campi pubblici definiti per il Tipo corrente.

Naturalmente, un'altra domanda sarebbe "perché hai campi pubblici?" - proprietà preferibili. Come astrazione, nota che la riflessione non è l'unica opzione: è anche possibile che un tipo esponga le sue proprietà al volo in fase di esecuzione (come come un DataTable DataTable / DataView espone le colonne come proprietà).

Per supportare questo (pur supportando anche oggetti semplici), dovresti usare TypeDescriptor :

        foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
        {
            Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
        }

Ciò consente anche numerose opzioni di estensibilità, ad esempio, accelerando la riflessione (senza modificare alcun codice).

    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());
            }
        }
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top