2009-07-06 5 views
0

Ich habe ein Projekt, in dem ich alle Variablen aus einer Struktur in einer anderen Klasse abrufen und alle ihre Namen zu einem Kombinationsfeld in einem Formular hinzufügen müssen. Mein Hauptproblem im Moment ist das Durchlaufen der Struktur in einer Weise, dass ich jede Variable einzeln in das Kombinationsfeld einfügen kann. Ich habe versucht, dies zu tun:Abrufen aller Variablen in einer Struktur unbekannter Größe (C#)

 msgVars vars = new msgVars(); 
     foreach (object obj in vars) 
     { 
      comboBox1.Items.Add(GetName(obj)); 
     } 

aber wie Sie wahrscheinlich wissen, kann man nicht durch eine Struktur auf diese Weise durchlaufen. Gibt es eine Möglichkeit, dies zu tun, ohne die Variablen fest zu codieren?

Auch als Referenz, das die Funktion GetName ist:

static string GetName<T>(T item) where T : struct 
{ 
    var properties = typeof(T).GetProperties(); 
    if (properties.Length == 1) 
    { 
     return properties[0].Name; 
    } 
    else 
    { 
     return null; 
    } 
} 
+0

Wie wäre es durch die Eigenschaften der Art von Vars Iterieren? –

+0

Definieren Sie "Variablen aus einer Struktur". –

+0

Sie meinten "Eigenschaften", oder? Bitte bearbeiten Sie Ihre Frage, um das zu beheben. –

Antwort

0

Wenn Sie nach einem Weg suchen Eigenschaften einer Struktur zuzugreifen (oder Klasse) zur Laufzeit ohne Code Vorgeben, die von Eigenschaften festgelegt, Was Sie wahrscheinlich brauchen, ist Reflexion.

Hier ist ein Beispiel:

struct MyStruct 
{ 
    private readonly int m_Age; 
    private readonly string m_LastName; 
    private readonly string m_FirstName; 

    public int Age { get { return m_Age; } } 
    public string LastName { get { return m_LastName; } } 
    public string FirstName { get { return m_FirstName; } } 

    public MyStruct(int age, string last, string first) 
    { 
     m_Age = age; 
     m_LastName = last; 
     m_FirstName = first; 
    } 
} 

class StructReflection 
{ 
    public static void Main(string[] args) 
    { 
     var theStruct = new MyStruct(40, "Smith", "John"); 
     PrintStructProperties(theStruct); 
    } 

    public static void PrintStructProperties(MyStruct s) 
    { 
     // NOTE: This code will not handle indexer properties... 
     var publicProperties = s.GetType().GetProperties(); 
     foreach (var prop in publicProperties) 
      Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(s, null)); 
    } 
} 
0

Sie versuchen, mithilfe von Reflektion könnte. Wie wäre es mit dem Speichern der Informationen in einer Hashtable?

public Hashtable GetPropertyInfo(Person person) 
{ 
    var properties = new Hashtable(); 
    PropertyInfo[] propInfo = person.GetType().GetProperties(); 
    foreach (PropertyInfo prop in propInfo) 
    { 
     properties.Add(prop.Name, prop.GetValue(person, null)); 
    } 

    return properties; 
} 

Dann könnten Sie die Informationen schreiben über:

var person = new Person() 
Person.Name = "Test"; 
Person.Age = 21; 

var PropertyInfo = GetPropertyInfo(person); 
foreach (string key in PropertyInfo.Keys) 
{ 
    Console.WriteLine("{0} = {1}", key, PropertyInfo[key]);  
} 
0

Eine Struktur ist eine Einheit, nicht eine Sammlung von Variablen. Dies bedeutet, dass Sie nicht über seine Eigenschaften "iterieren" können. Was Sie tun müssen, ist eine Auflistung der Eigenschaftsnamen zu erhalten und darüber zu iterieren. Ihre GetName-Funktion kann dies nicht tun, da sie nur den Namen der ersten Eigenschaft zurückgibt.

Um die Eigenschaftsnamen zu einer Combo alles, was Sie tun müssen, um hinzuzufügen ist:

var vars = new msgVars(); 
foreach(var name in GetNames(vars)) 
    comboBox1.Items.Add(name); 

In der Tat, die Eigenschaftsnamen bekommen ist so einfach, dass Sie completley und schreiben los GetNames bekommen konnten nur

foreach (var prop in typeof(msgVars).GetProperties()) 
     comboBox1.Items.Add(prop.Name); 

Es gibt verschiedene Möglichkeiten, wie Sie GetNames schreiben können, um eine Sammlung von Namen zurückzugeben. Sie können eine Liste mit den Namen der Eigenschaft füllen, obwohl die einfachste zurückgeben einen Iterator wie diese zu haben ist:

public static IEnumerable<string> GetNames<T>(T obj) where T:struct 
{ 
    var properties = typeof (T).GetProperties(); 
    foreach (var propertyInfo in properties) 
    { 
     yield return propertyInfo.Name; 
    } 
} 

Schließlich Sie nicht wirklich eine Instanz Ihrer Struktur an die Methode übergeben müssen, wie Sie listet die Namen der Struktureigenschaften auf, nicht ihre Werte. Sie können GetNames umschreiben wie diese

public static IEnumerable<string> GetNames<T>() where T:struct 
{ 
    var properties = typeof (T).GetProperties(); 
    foreach (var propertyInfo in properties) 
    { 
     yield return propertyInfo.Name; 
    } 
    } 

und die Namen laden wie diese

foreach(var name in GetNames<msgVars>()) 
     comboBox1.Items.Add(name);