Laden...

auf Variablen zugreifen mit deren Namen

Erstellt von DamiondeLui vor 2 Jahren Letzter Beitrag vor 2 Jahren 275 Views
D
DamiondeLui Themenstarter:in
4 Beiträge seit 2022
vor 2 Jahren
auf Variablen zugreifen mit deren Namen

Hiho,

wahrscheinlich lacht ihr mich jetzt alle aus, aber ich hab nie Programmieren gelernt und mach es dennoch ( ich denke aber sehr oft sehr sehr umständlich )...

Also folgendes Problem, nehmen wir mal als Beispiel ein RPG. Ich hab da mehrere Helden und die haben Stats und Skills. Und jeder Skill hat z.b. einen Wert ( 0-Cap ), einen Wert für die Erfahrungspunkte ( 0 bis 2 Mio ) und einen Wert für den Cap, also Beispiel:
int smity
int smithyxp
int smitycap
int carpenter
int carpenterxp
int carpentercap
...

So nun hab ich z.b. beim Craftsystem die Items definiert, also z.b. ein Stuhl der braucht carpenter zum Herstellen... Die Pfeilspitzen brauchen aber Schmieden und so weiter und so weiter...

Wie kann ich nun hergehen und fragen:
gib mir den int wert der Variablen mit namen string name aus.
Also ich lese z.b. aus dem Craftsystem ich brauche "carpenter" ( also z.b. den string skill )
wie kann ich daraus fragen int val = skill.value?

die umständliche Variante wäre mit einer Funktion mit einer switch-Anweisung also z.b.
public int GetIntValue( string name )
switch ( name )
case "carpenter": return carpenter;
case "carpenterxp": return carpenterxp;
....

Aber das geht doch bestimmt auch einfacher, oder?

16.807 Beiträge seit 2008
vor 2 Jahren

Sowas macht man (schmutzigerweise) in Script-Sprachen, nicht in .NET und Konsorten.
Siehe [FAQ] Variablennamen zur Laufzeit zusammensetzen / Dynamisches Erzeugen von Controls

D
DamiondeLui Themenstarter:in
4 Beiträge seit 2022
vor 2 Jahren

hmm, ok also die Antwort war versteckt aber enthalten. Es geht also nicht "einfacher".

Es ist ja kein Unterschied ob ich z.b. ein Dictionary anlege mit allen Werten auf die ich dann zugreifen kann ( muß ich ja auch einmal mit allen Werten füllen, sprich einmal muß ich hergehen und die ganzen Variablen als Variablennamen und dem entsprechenden Wert dort eintragen ), oder mit einer Switch-Anweisung die auslesen kann, in beiden Fällen muß ich jede Variable die ich hab ( weit über 100 ) dort aufnehmen.

Schade, in Pearl ( ja, ja lange her ) ging das.

Oki dann weiß ich das ich beim nächsten mal keine Variablen mehr anlege, sondern gleich ein Dictionary<string, value ( int oder float, oder double, oder auch ein string... )> 🙂

4.931 Beiträge seit 2008
vor 2 Jahren

Wenn deine Skills jeweils aus 3 Werten bestehen, so fasse sie zu einer Klasse zusammen:


class Skill
{
  public int Value { get; set; }
  public int XP { get; set; }
  public int Cap { get; set; }
}

So brauchst du nicht für jeden Skill 3 Variablen anlegen, sondern nur noch eine:


Skill smity = new();
Skill carpenter = new();

Und zugreifen dann per . Operator, z.B.:


int xp = smity.XP;
// oder
carpenter.Value += 10;

Und auch diese Klassenobjekte kannst du dann in ein Dictionary packen:


var dictionary = new Dictionary<string, Skill>()
{
  { "smity", smity },
  { "carpenter", carpenter },
  // ...
};

Und wenn du gleich schon die Skills initialisieren willst, dann füge noch passende Konstruktoren hinzu, z.B.


class Skill
{
  public Skill(int xp, int cap)
  {
    XP = xp;
    Cap = cap;
  }
 
  // ... (wie oben)
}

Und dann z.B. so initialisieren:


Skill smity = new(10, 100);
Skill carpenter = new(20, 200);

PS: Das Dictionary brauchst du aber nur für Benutzereingaben, in deiner Programmlogik selbst solltest du immer direkt die Variablen benutzen.
Alternativ könntest du auch ein Enum deiner Skills anlegen und damit eine Liste anlegen (anstatt der Einzelvariablen):


enum SkillType
{
  Smity,
  Carpenter,
  // ...
  MaxSkillTypes // optional, aber für den Programmcode oftmals sinnvoll die Anzahl der Enumerationswerte zu kennen!
}

public readonly List<Skill> Skills = new() // nur diese Liste ist 'readonly', nicht die Einträge (Skills) selbst
{
   // Liste mit Werten füllen (entsprechend der SkillType-Reihenfolge)
   new(10, 100), // Smity
   new(20, 100), // Carpenter
   // ...
};

Und dann eine Hilfsmethode zum Zugriff auf diese Liste


public Skill GetSkill(SkillType skillType)
{
  return Skills[(int)skillType];
}

Und Aufruf dann z.B.


var smity = GetSkill(SkillType.Smity);
smity.Value -= 42;

Mittels der statischen Enum-Klasse kannst du dann auch die Enum-Konstanten als String ansprechen (GetName, Parse bzw. besser TryParse), so daß du auf das Dictionary verzichten kannst.

16.807 Beiträge seit 2008
vor 2 Jahren

Schade, in Pearl ( ja, ja lange her ) ging das.

In Perl programmiert man auch anders als in C# (+ ähnliche Sprachen).
Versuch nich blind Paradigmen zu übernehmen. Da wirst nicht der erste sein, der an einem solchen Versuch scheitert wird - aber leider auch nicht der letzte..

Th69 zeigt das absolut korrekte Vorgehen.

2.078 Beiträge seit 2012
vor 2 Jahren

... wobei ich beim letzten Punkt keine Liste, sondern wieder ein Dictionary nehmen würde, mit dem Enum als Key.
Bei der Umsetzung mit der Liste sind Reihenfolge (und damit Werte) im Enum direkt von der Reihenfolge der Listeneinträge ab - also eine Sollbruchstelle, wenn man mal nicht aufpasst.

16.807 Beiträge seit 2008
vor 2 Jahren

Das is aber ne Detailfrage und hängt davon ab, ob es am Ende wirklich nen Enum wird.
Den Sinn - hier OOP anzuwenden, wie es in solchen Sprachen wie C# halt gedacht ist - wird ja vermittelt 🙂

D
DamiondeLui Themenstarter:in
4 Beiträge seit 2022
vor 2 Jahren

@Th69:
Vielen Dank, das war sehr verständlich und wird mir sicher weiter helfen 🙂

@Abt:
Du hast leicht Reden 🙂 Ich hab vor rund 30 Jahren Perl mittels eines Buches gelernt und vielleicht ein paar wenige Jahre angewendet ( für Webseiten um da z.b. ein Gästebuch zu realisieren. ). Die Wahl fiel auf Perl, weil es eben nicht nur ans Web gebunden ist wie z.b. php.
Ja und dann hab ich durch Zufall bei einem Online-Spiel ( Ultima Online ) das es da private, kostenlose Server ( Shards ) gab und die hatten eigene Scriptsprachen. Da ein wenig drin rumgebastelt und dann kam auch schon RunUO raus, also ein Server-Software-Paket basierend auf c#, mit welchen man seinen eigenen Server aufbauen konnte. Das hab ich damals gemacht und hatte ehrlich so gut wie keine Probleme mich in c# ( also den bereits vorhandenen Scripten ) zurecht zu finden. Und ja diese waren definitiv Objektorientiert und das fand ich eigentlich sehr verständlich.
Dann aber lange Jahre lang nur noch für Webseiten eingesetzt ( also 90% Datenbank-Abfragen, Foren, kleine Browsergames etc... ) und da braucht man nicht wirklich Objekte.

Jetzt hab ich Unity3D entdeckt und hey es nutzt c#....

Also ran ans Spiel 🙂

Aber natürlich bin ich von den Webseiten und der nicht Objektorientiertheit dieser doch ziemlich verhunzt... Und ich hab es ja auch nie wirklich gelernt und bin auch nicht mehr ganz der jüngste ( Baujahr 68 ).

Der Witz dabei, ich hab tatsächlich bei einigen Dingen ganz von alleine Klassen angelegt und somit Objekte erzeugt. Also z.b. hab ich beim Herstellen CraftRessources und Craftitems erzeugt auf die ich wunderbar zugreifen kann... Aber mir kam das ganze nicht in den Sinn für die Daten zu verwenden die ich vom Server lade...

Aber vielen vielen Dank für die Hilfe, ihr habt mir wirklich sehr geholfen, jetzt muß ich noch kurz darüber nachdenken wie ich es mache ( das mit den Füllem der Werte etc.. ) und dann umstricken 🙂 Bin aber noch ziemlich am Anfang, sollte also noch leicht gehen 🙂

4.931 Beiträge seit 2008
vor 2 Jahren

Hallo,

Schade, in Pearl ( ja, ja lange her ) ging das.

Ich hab vor rund 30 Jahren Perl mittels eines Buches gelernt...

Und ich dachte schon, du meintest wirklich PEARL und nicht Perl. 😉

D
DamiondeLui Themenstarter:in
4 Beiträge seit 2022
vor 2 Jahren

uff da siehst mal wie lange das her ist 🙂
Perl natürlich ( musste aber auch erst die beiden Artikel bei Wikipedia überfliegen, aber CPAN kam mir dann doch extrem bekannt vor 🙂 )