Richard
Richard

Reputation: 529

Looping through Class Variables using reflection

I want to loop through a Class and list it's Variables. This has been asked multiple times on SO, and I have tried all the answers.

For some reason I can't get the solutions to work. When I run the code below (which should loop through the class twice, just to try different ways), the answer just reads 'Test1' meaning that it hasn't looped through the class.

Does anyone know why the loops aren't running?

public partial class Tables : Form
{
  private void dataGridViewNodes_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
        Debug.WriteLine("test1");
        //Simple Test
        foreach (PropertyInfo prop in typeof(NodeHeaders).GetProperties())
        {
            Debug.WriteLine("test2");
            Debug.WriteLine(prop.Name);
        }

        //the above should have looped through the class so let's try again
        var nodeHeaders = new NodeHeaders();
        Type t = nodeHeaders.GetType();
        string fieldName;
        object propertyValue;

        // Use each property of the object passed in
        foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
        {
            // Get the name of the property
            fieldName = pi.Name;

            // Get the value of the property
            propertyValue = pi.GetValue(nodeHeaders, null);
            Debug.WriteLine("test3");
            Debug.WriteLine(fieldName + ": " + (propertyValue == null ? "null" : propertyValue.ToString()));
        }

    }
}

public class NodeHeaders
{
    public static string node_name = "Conduit Name";
    public static string x = "Easting (m)";
    public static string y = "Northing (m)";
    public static string z_cover = "Cover Level (m)";

}

EDIT:

Based on a comment form Nico Schertler explaining that I need to cycle through fields and not properties I have also tried the following with the same result.

Type type = typeof(NodeHeaders);
foreach (var p in type.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
{
    var v = p.GetValue(null); // static classes cannot be instanced, so use null...
    Debug.WriteLine(v.ToString());
}

Upvotes: 2

Views: 1241

Answers (2)

Ibrahim Malluf
Ibrahim Malluf

Reputation: 657

Will this work for you??

public class NodeHeaders
{
    public static string node_name = "Conduit Name";
    public static string x = "Easting (m)";
    public static string y = "Northing (m)";
    public static string z_cover = "Cover Level (m)";

}

class Program
{




    static void Main(string[] args)
    {

        DataGridViewNodes_CellValueChanged();



    }

private static void DataGridViewNodes_CellValueChanged()
{
        try
        {


    foreach (FieldInfo prop in typeof(NodeHeaders).GetFields())
    {

        object item = prop.GetValue(null);
                Console.WriteLine($"{prop.Name} = {item.ToString()}");
    }

        }
        catch (Exception ex)
        {

            throw;
        }

        Console.ReadKey();

}

}

Upvotes: 1

Mel Gerats
Mel Gerats

Reputation: 2262

Since the things you want to access are public static fields, you should use t.GetFields(BindingFlags.Static | BindingFlags.Public)

foreach (var field in typeof(NodeHeaders).GetFields(BindingFlags.Static | BindingFlags.Public))
{        
    // Get the name of the property
    string fieldName = field.Name;
    // Get the value of the property
    object propertyValue = field.GetValue(null);
    Console.WriteLine("test3");
    Console.WriteLine(fieldName + ": " + (propertyValue == null ? "null" : propertyValue.ToString()));
}

That will properly access the field values:

enter image description here

Upvotes: 2

Related Questions