Цикл через постоянные члены класса

У меня есть класс с постоянными строками. Я хотел бы бросить все эти строки в выпадающую коллекцию. Каков наилучший способ сделать это? Это то, что у меня есть сейчас и в теории, я бы подумал, что это лучший способ сделать это.

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

Проблема в том, что это возвращает ошибку в foreach: "... не содержит общедоступного определения для GetEnumerator". Я попытался создать GetEnumerator, но я не увенчался успехом, и в прошлом я не работал с GetEnumerator.

Любая помощь очень ценится!

Ответ 1

Вы можете использовать отражение, чтобы перебрать все свойства:

public DropDownItemCollection TestCollection
{
    var collection = new DropDownItemCollection();
    var instance = new TestClass();
    foreach (var prop in typeof(TestClass).GetProperties())
    {
        if (prop.CanRead)
        {
            var value = prop.GetValue(instance, null) as string;
            var item = new DropDownItem();
            item.Description = value;
            item.Value = value;
            collection.Add(item);
        }
    }
    return collection;
}

Ответ 2

Немного поздно, но разве это не лучшее решение?

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

Если вам нужны имена, которые вы можете сделать

fi.GetValue(null)

внутри цикла.

Ответ 3

Вы можете реализовать метод, который возвращает строки:

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

В противном случае вы должны посмотреть на отражение, чтобы вернуть статические и строковые свойства, а затем получить значения, вызвав их.

С уважением GJ

Ответ 4

Вы можете использовать отражение для цикла, вызвав свойства класса:

var instance = new TestClass();
foreach(PropertyInfo pi in typeof(TestClass))
{
      var val = pi.GetValue(instance,null);
}

Ответ 5

У меня была такая же проблема; чтобы получить все константы моего класса (а не свойства!). На основе самого популярного ответа (для свойств) и ответа Джона (для констант) я написал это. Я тестировал его, и он работает хорошо.

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

Ответ 6

Вам нужно использовать отражение, чтобы получить имя каждой строки из вашего настраиваемого типа, а затем также/необязательно получить значение каждой из этих строк...

Что-то вроде этого:

TestClass theClass = new TestClass();

foreach (PropertyInfo property in theClass.GetType().GetProperties())
{

    Console.WriteLine(property.Name);
    Console.WriteLine(property.GetValue(theClass, null));
}