2016-03-23 9 views
0

Ich hatte einige Probleme beim Versuch, dies auszuarbeiten, und es ist sicherlich möglich, dass ich einfach nicht an den richtigen Stellen suchen, aber ich habe Probleme Entwerfen einer Klasse, die eine enthält Sammlung einzelner Eigenschaften und unterstützt auch einfache Auflistung aller Eigenschaften in dieser Klasse.C# Entwerfen einer Klasse zur Unterstützung der Enumeration

Zum Beispiel:

public class CharacterStats 
{ 
    public List<BaseStat> StatList { get; set; } 

    private BaseStat Level { get; set; } 
    private BaseStat Health { get; set; } 
    private BaseStat Damage { get; set; } 
    private BaseStat Defense { get; set; } 
} 

private void InitializeList() 
{ 
    StatList = new List<BaseStat> 
    { 
     Level, 
     Health, 
     Damage, 
     Defense, 
    }; 
} 

Letztlich jede dieser Eigenschaften ist wichtig, in seinem eigenen Recht, aber es gibt bestimmte Fälle, in denen ich durch all diese Eigenschaften in einer Schleife will und führen Kontrollen auf jedem von ihnen .

Ich bin (irgendwie) vertraut mit reflection, aber es fühlt sich klobig und unnötig an, über die Eigenschaften auf diese Weise zu iterieren. Ich habe jetzt das eingerichtet, um die Eigenschaften in eine List<BaseStat> zu rollen und auf diese Weise zu iterieren, aber ich bin immer noch nicht ganz sicher, ob das die "richtige" Implementierung ist.

Einige Dinge zu beachten:

  • Je nach Nutzung, ich mag einen Hinweis auf eine einzige Eigenschaft aktualisieren (nach Namen), OR Update die gesamte Sammlung (vermutlich durch Aufzählung).
  • Beim Aktualisieren der gesamten Sammlung wird (wahrscheinlich) mit einem anderen Objekt vom Typ CharacterStats (oder etwas ähnlichem), das Modifikatoren für einige oder alle dieser Eigenschaften enthält.

Idealerweise ich bin auf der Suche nach einer Lösung dieser Klasse als eine Sammlung darstellen, wo ich einfach einen einzelnen Wert oder mehrere Werte nach Bedarf aktualisieren.

Verwenden Sie eine List<T> oder reflection den Weg zu gehen, oder gibt es eine bessere Methode, die ich nicht berücksichtigt habe? Ich habe in den letzten Tagen viel in den Interwebs herumgestöbert, um eine Lösung zu finden, aber ich habe entweder Informationen gefunden, die (glaube ich) irrelevant sind, oder mich einfach weiter verwirrt.

Sachlich unter Berücksichtigung der potenziellen Performance-Probleme (ich dieses Argument gehört habe in Bezug auf reflection) und besonders einfache Bedienung und Lesbarkeit, wie soll ich diese Klasse so auszugestalten, dass ich mit ihm arbeiten kann, wie ich habe beschrieben?

Bitte kommentieren Sie, wenn weitere Informationen zur Klärung benötigt werden.

+0

Verwenden Sie Code als Beispiel, warum nicht eine "Liste "? Obwohl ich nicht denke, dass es eine sehr nette Lösung ist. –

+0

Sie könnten eine Eigenschaft auf Ihre Klasse vom Typ IEnumerable haben und nur Rendite alle Eigenschaften zurückgeben? – juunas

+0

@DarrenYoung Entschuldigung dafür, dass ich den Code verlassen habe, aber das mache ich gerade. Das funktioniert, aber ich versuche herauszufinden, ob es eine bessere Möglichkeit gibt, diese Daten darzustellen. Ich habe meinen List <> Code zum Beispiel hinzugefügt. – levelonehuman

Antwort

1

Sie könnten auch in die ExpandoObject Klasse, die mit dynamischen Eigenschaften im Hinterkopf gemacht wird, und ermöglicht auch die Aufzählung von diesen (durch die Implementierung der IDictionary<string, object> Schnittstelle.


Beachten Sie, dass Ihr Beispielcode ein großes Problem hat: es fügt die Eigenschaften früh in der Liste (oder Wörterbuch, wenn Sie das verwenden waren), aber diese sind nicht synchron mit Änderungen an die realen Objekteigenschaften gehalten . Wenn Sie eine handgemachte Lösung halten wollen, die etwa so allgemein wie die ist, die Sie gemacht haben, würde ich lieber tun:

public class CharacterStats 
{ 
    public IEnumerable<BaseStat> GetStats() { 
     yield return Level; 
     yield return Health; 
     yield return Damage; 
     yield return Defense; 
    } 

    public BaseStat Level { get; set; } 
    public BaseStat Health { get; set; } 
    public BaseStat Damage { get; set; } 
    public BaseStat Defense { get; set; } 
} 

Die Aufzählung hier nicht „kommunizieren“, um die Art der Immobilie, so dass sollte entweder durch den konkreten Typ abgedeckt werden (zB durch Klassen wie LevelStat, HealthStat etc.) oder indem eine Enumeration von KeyValuePair mit einem Namen oder enum als Schlüssel zurückgegeben wird.

+0

Ihre Notiz über das Problem mit meinem Code: Ich sollte zuerst beachten, dass ich noch lerne, aber ich hatte den Eindruck, dass ich nur Referenzen dieser Eigenschaften (da sie Objekte sind) zu der Liste hinzufügen; Ist das nicht der Fall? Es ist auch erwähnenswert, dass ich den Code nicht gepostet habe, wo ich diese Eigenschaften initialisiere. Können Sie mir das Problem mit meiner Implementierung erklären und wie ich es beheben könnte? Ich mag die Idee des IEnumerable. Am Ende versuche ich es vielleicht als nächstes. Vielen Dank! – levelonehuman

+0

@levelonehuman In Ihrer 'InitializeList'-Methode kopieren Sie den in der Eigenschaft gespeicherten Verweis auf Ihre Liste - keinen Verweis auf die Eigenschaft selbst. Daher ist Ihre Liste eine Momentaufnahme dessen, was die Eigenschaften waren, als 'InitializeList' ausgeführt wurde, und weitere Änderungen an den Eigenschaften (oder Elementen in der Liste) haben keine Auswirkung auf die andere. Deshalb schlage ich den Aufzählungscode vor; Es wird jedes Mal ausgeführt, wenn Sie die Enumeration ausführen, und gibt dabei die in den Eigenschaften gespeicherten Referenzen zum Zeitpunkt der Enumeration aus. – Lucero

+0

Genau das habe ich gesucht! Ich denke, ich war mit meinem Testcode noch nicht weit genug gekommen, um das zu sehen - danke für die Info. – levelonehuman

4

Verwenden Sie eine Dictionary<String,BaseStat>.
Sie können dic.Keys iterieren oder auf dic["Level"] zugreifen.

Bonuspunkte, wenn Sie tatsächlich einen enum als Schlüsseltyp verwenden, um Tippfehler zu vermeiden.

+1

Sie können über 'dic.Values' iterieren, um auf alle Werte zuzugreifen, ohne die Schlüssel nachschlagen zu müssen. – Floremin

+2

Es ist nichts falsch daran, eine Antwort aus Kommentaren zu kopieren, aber Sie sollten zumindest [die ursprüngliche Quelle] bestätigen (https://stackoverflow.com/questions/36183703/c-sharp-designing-a-class-to-support-enumeration) # comment60002919_36183703). –

+0

@PeterDuniho: Ich schrieb meine Antwort zur gleichen Zeit wie thiw Kommentar geschrieben wurde. – ths

Verwandte Themen