Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop through constant members of a class

Tags:

c#

class

I have a class with constant strings in it. I'd like to throw all of those strings into a drop down collection. What is the best way to do this? This is what I have now and in theory, I would think that it would be the best way to do this.

public class TestClass
{
    private const string _testA = "Test A";
    private const string _testB = "Test B";

    public string TestA
    {
        get { return _testA; }
    }

    public string TestB
    {
        get { return _testB; }
    }
}

public DropDownItemCollection TestCollection
{
    DropDownItemCollection collection = new DropDownItemCollection();
    TestClass class = new TestClass();

    foreach (string testString in class)
    {
        DropDownItem item = new DropDownItem();
        item.Description = testString;
        item.Value = testString;
        collection.Add(item);
    }

    return collection;
}

The problem is that this returns an error on the foreach: "...does not contain a public definition for GetEnumerator." I've tried to create a GetEnumerator but I've been unsuccessful and I haven't worked with GetEnumerator in the past.

Any help is greatly appreciated!

like image 367
divided Avatar asked Feb 14 '11 16:02

divided


3 Answers

I just had the same challenge; to get all constants of my class (not properties!). Based on the most popular answer (for properties) and John's answer (for constants) I wrote this. I tested it and it works well.

private List<string> lstOfConstants= new List<string>();
    foreach (var constant in typeof(TestClass).GetFields())
    {
        if (constant.IsLiteral && !constant.IsInitOnly)
        {
            lstOfConstants.Add((string)constant.GetValue(null));
        }
    }
like image 67
penCsharpener Avatar answered Sep 23 '22 01:09

penCsharpener


A little late but wouldn't this be a better solution?

http://weblogs.asp.net/whaggard/archive/2003/02/20/2708.aspx

private FieldInfo[] GetConstants(System.Type type)
{
    ArrayList constants = new ArrayList();

    FieldInfo[] fieldInfos = type.GetFields(
        // Gets all public and static fields

        BindingFlags.Public | BindingFlags.Static | 
        // This tells it to get the fields from all base types as well

        BindingFlags.FlattenHierarchy);

    // Go through the list and only pick out the constants
    foreach(FieldInfo fi in fieldInfos)
        // IsLiteral determines if its value is written at 
        //   compile time and not changeable
        // IsInitOnly determine if the field can be set 
        //   in the body of the constructor
        // for C# a field which is readonly keyword would have both true 
        //   but a const field would have only IsLiteral equal to true
        if(fi.IsLiteral && !fi.IsInitOnly)
            constants.Add(fi);           

    // Return an array of FieldInfos
    return (FieldInfo[])constants.ToArray(typeof(FieldInfo));
}

If you need the names you can do

fi.GetValue(null)

inside the loop.

like image 36
John Avatar answered Sep 23 '22 01:09

John


You could implement a method that yields the strings:

public Ienumerable<string> GetStrings(){
   yield return TestA;
   yield return TestB;
}

Else you should look into reflection to return the properties that are static and string and then get the values by calling them.

Regards GJ

like image 21
gjvdkamp Avatar answered Sep 24 '22 01:09

gjvdkamp