C# Werte aus vererbten Objekten in ArrayList aufrufen?
Guten Tag,
ich bin neu in C# und versuche gerade eine kleine Klasse zum üben zu erstellen, jedoch bin ich auf ein Problem gestoßen, bei dem ich keine Ahnung habe. Ich versuche gerade von objekten, die in einer ArrayList sind, Werte zu entziehen (per selbsterstellter ToString()), aber ich kann dies leider irgendwie nicht. Es kann auch sein, dass das anders ist als in Java.
Ich versuche halt es so wie in Java zu machen, nähmlich: ArrayList[i].ToString() , bekomme aber nichts raus.
public classes(int hp, String name, int def, int atk)
{
this.name = name;
this.hp = hp;
this.def = def;
this.atk = atk;
}
public void setHp(int hp)
{
this.hp = hp;
}
public void setDef(int def)
{
this.def = def;
}
public int getHp()
{
return hp;
}
public int getAtk()
{
return atk;
}
public abstract String ToString();
public abstract void print();
}
class Attacker :classes
{
public int critrate = 15;
public int critdmg = 50;
public int piercing = 0;
public int hp = 0;
public int def = 0;
public int atk = 0;
public String name = "Guest";
public Attacker(int hp, int def, int atk, String name, int critrate, int critdmg, int piercing) : base(hp, name, atk, def)
{
this.hp = hp;
this.def = def;
this.atk = atk;
this.name = name;
this.piercing = piercing;
this.critdmg = critdmg;
this.critrate = critrate;
}
public override void print()
{
Console.WriteLine(ToString());
}
public override string ToString()
{
return "Username: " + name + "\nHp: " + hp + "\nDefense: " + def + "\nDamage: " + atk
+ "\nPiercechance: " + piercing + "%\nCritdmg: " + critdmg + "\nCritrate: " + critrate + "%"
;
}
}
static void Main(string[] args)
{
Attacker d = new Attacker(50, 20, 10, "d", 10, 15, 0);
Attacker e = new Attacker(100, 30, 5, "e", 2, 3, 2);
Attacker f = new Attacker(1000, 1, 0, "f", 0, 0, 0);
Attacker g = new Attacker(2, 0, 100, "g", 20, 200, 10);
Monsters.Add(d);
Monsters.Add(e);
Monsters.Add(f);
Monsters.Add(g);
Monsters.ToString();
Ich hab das dann zu Monsters.ToString() umgeändert, jedoch kein Erfolg.
Danke im Vorraus
2 Antworten
Genauso wie in Java musst du Strings, die du ausgeben lassen möchtest, auch an den Ausgabekanal weiterreichen.
Console.WriteLine(Monster.ToString());
Du würdest an der Stelle aber nur eine Ausgabe wie:
System.Collections.ArrayList
bekommen, da du versuchst, ein ArrayList-Objekt auszugeben. Um die Beschreibungen der einzelnen Elemente bekommen, musst du, wie auch in Java, in irgendeiner Form über die einzelnen Elemente iterieren.
foreach (Attacker monster in Monsters)
{
Console.WriteLine(monster.ToString());
}
Da deine abstrakte Klasse die ToString-Methode überdeckt, die üblicherweise von Object geerbt wird, ist es notwendig, die Methode in der Schleife explizit je Element aufzurufen.
Entferne diese Deklaration:
public abstract String ToString();
dann klappt es auch so:
foreach (var monster in Monsters)
{
Console.WriteLine((monster));
}
Oder:
Console.WriteLine(string.Join(Environment.NewLine, Monsters.ToArray()));
Statt einer ArrayList ist in C# eine List<> meist die bessere Wahl, da sie generisch ist. So könntest dir späteres Casting auch sparen.
var monsters = new List<Attacker>();
// add monsters ...
Console.WriteLine(string.Join(Environment.NewLine, Monsters));
Des Weiteren wäre es gut, wenn du dir die üblichen C#-Konventionen angewöhnen würdest. Klassennamen beginnen genauso wie in Java mit einem Großbuchstaben, in C# gilt das ebenso für Methoden. Felder werden meist mit einem führenden Kleinbuchstaben geschrieben.
Diese vier Felder in der Subklasse
public int hp = 0;
public int def = 0;
public int atk = 0;
public String name = "Guest";
überdecken im Übrigen wohl die Felder der Basisklasse. Es wäre sicherlich passender, sie nur von der Basisklasse zu erben, um doppelten Code einzusparen. Ihre initialen Werte werden zudem eh bei Objekterstellung überschrieben, daher sind die Initialisierungen ohne Nutzen.
Ganz einfach weil deine ArrayList ihre Elemente nur als Object-Instanzen kennt. Du musst jedes Element, welches du aus ihr herausziehst, entweder erst explizit casten oder du verwendest von Anfang an einen generischen Containertyp wie List.
Vergiss das mit den Getter- und Setter, so wie du es aus Java kennst. In C# gibt es dafür Properties.
Danke, ich wollte noch fragen, ich habe jetzt noch ein paar getter und setter eingefügt. Wieso werden die mir nicht angezeigt wenn ich versuche aus der ArrayList die Daten auszurufen? Die Getter und Setter sind in der "classes" Klasse.