2011-02-14 11 views
9

Tengo una clase con cadenas constantes en ella. Me gustaría incluir todas esas cadenas en una colección desplegable. ¿Cuál es la mejor manera de hacer esto? Esto es lo que tengo ahora y, en teoría, creo que sería la mejor manera de hacerlo.Loop a través de miembros constantes de una clase

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

El problema es que este devuelve un error en el foreach: "... no contiene una definición pública para GetEnumerator." Intenté crear un GetEnumerator pero no tuve éxito y no trabajé con GetEnumerator en el pasado.

¡Cualquier ayuda es muy apreciada!

Respuesta

9

Se podría utilizar la reflexión para recorrer todas las propiedades:

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

Para mí esto no devolvió nada (parece correcto si devolver propiedades pero los valores de const no son propiedades) así que no sé cómo se subió tanto. La respuesta de @ John a continuación funciona para los miembros de la cadena const. – christutty

8

podría implementar un método que produce las cadenas:

public Ienumerable<string> GetStrings(){ 
    yield return _TestA; 
    yield return _TestB; 
} 

Cosa que usted debe buscar en la reflexión para devolver las propiedades que son estáticos y de cadena y luego obtienen los valores llamándolos.

Saludos GJ

4

Puede utilizar la reflexión para trought bucle de las propiedades de clase:

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

Es necesario utilizar la reflexión para obtener el nombre de cada cuerda de su tipo personalizado, y luego también/opcionalmente llegar el valor de cada una de esas cadenas ...

Algo como esto:

TestClass theClass = new TestClass(); 

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

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

Esto obtiene las propiedades, no las constantes (como pregunta) – user1191559

10

Un poco tarde pero ¿no sería esta una mejor solución?

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

Si necesita los nombres que puede hacer

fi.GetValue(null) 

dentro del bucle.

+0

Esto está dando resultados extraños para mí. Decidí una clase que contenía una configuración pública de todos los tipos incorporados, y este método siempre ignora los decimales, por alguna razón 'const decimal pública = 1.0m;' tiene IsInitOnly = true – MrLore

+0

Parece que no soy el primero en notarlo esto de hecho: https://codeblog.jonskeet.uk/2014/08/22/when-is-a-constant-not-a-constant-when-its-a-decimal/ – MrLore

1

Acabo de tener el mismo desafío; para obtener todas las constantes de mi clase (¡no propiedades!). Basado en la respuesta más popular (para las propiedades) y la respuesta de John (para las constantes) escribí esto. Lo probé y funciona bien.

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