Wie kann ich in C# Unterklassen aufrufen?
XavenInject.GetModuleManager().GetModules()
Eine Liste aller hinzugefügten Klassen. In diesem Fall nur die Klasse Flight.cs, welche von der Module.cs Klasse erbt.
Die Klasse Module.cs und Flight.cs besitzen beide die Methode onUpdate(). Diese wird nur von der Klasse Module.cs ausgeführt.
Ich möchte jedoch, dass sie in allen hinzugefügten Klassen ausgeführt wird, also auch Flight.cs
2 Antworten
Ich beziehe mich hier auf die Kommentare unter der Antwort von Dultus:
Und das, was Dultus schreibt ist - sorry - grober Unfug.
Das, was Du erreichen willst, ist eine klassische Anforderung der Objektorientierung.
Die OnUpdate-Methode muss virtual sein und die ableitenden Klasse überschreiben (override) sie:
static void Main(string[] args) {
List<Module> Modules = new List<Module>();
Modules.Add(new Flight());
Modules.Add(new Speed());
foreach (Module m in Modules) {
m.OnUpdate();
}
}
class Module {
public virtual void OnUpdate() {
Console.WriteLine("Called in Module");
}
}
class Flight : Module {
public override void OnUpdate() {
base.OnUpdate();
Console.WriteLine("Called in Flight");
}
}
class Speed : Module {
public override void OnUpdate() {
base.OnUpdate();
Console.WriteLine("Called in Speed");
}
}
Man kann auch mit Reflection arbeiten, aber das ist unsicher, unnötig komplex und in 99,9...999% der Fälle völlig überflüssig.
Mit dynamic oder einem Interface Interface erreicht man dieses Ziel nicht, da sich beides nur mit der Existenz der Methode und ihren Aufruf beschäftigt. Man muss die Methode in den abgeleiteten Klassen aber immer noch überschreiben.
Einen Zwang zum Überschreiben der Methode und Aufrufen der Basis-Implementierung gibt es nicht, Du kannst aber mit einer zweiten abstrakten Methode tricksen.
Die Fragestellung habe ich auch erst nach dem Code + Ausgabe-Wunsch unter deiner Antwort verstanden :D
Also dieser Kommentar: Wie kann ich in C# Unterklassen aufrufen? (Computer, Programmieren, Vererbung) - gutefrage
Danke dir,
ich programmiere jetzt seit ungefähr 6 Jahren in Java und dort geht es genauso wie in meinem Code. Ich hab mich sowieso die ganze Zeit schon gefragt, wieso es so eine Kernfunktion der Objektorientierung nicht gibt, aber anscheinend schon, nur ein Wenig anders :)
Ist eigentlich ziemlich gleich, aber bei C# sind die Methoden nicht automatisch virtual, sondern müssen explizit als virtual deklariert werden.
Ich sehe, dass bei die Methode, die mit virtual deklariert ist, an sich nicht aufgerufen wird. Kann man das auch noch ändern?
Das "base" ist wie das "this", bloß für die Basis-Klasse.
Das "base.OnUpdate()" ruft also die Basis-Implementierung auf.
Du kannst das Module einfach als Flight Klasse callen.
if (m is Flight)
(m as Flight).OnUpdate();
Wenn du das so meinst.
Danke, das funktioniert. Es bleibt aber nicht bei der einen Flight Klasse, sondern kann beliebig mehr werden. Gäbs da ne Lösung?
Naja, kommt drauf an, welche Methode du denn nun verwenden möchtest!
Hilft dir das eventuell? Klingt mir zumindest nach Reflection, wüsste aber nicht, was du genau vorhast.
static void Main(string[] args) {
List<Module> Modules = new List<Module>();
Modules.Add(new Flight());
Modules.Add(new Speed());
foreach (Module m in Modules) {
m.OnUpdate();
}
}
class Module {
public void OnUpdate() {
Console.WriteLine("Called in Module");
}
}
class Flight : Module {
public void OnUpdate() {
Console.WriteLine("Called in Flight");
}
}
class Speed : Module {
public void OnUpdate() {
Console.WriteLine("Called in Speed");
}
}
Ausgabe:
Called in Module
Called in Module
Was ich möchte ist, dass in der Konsole das ausgegeben wird:
Called in Module
Called in Flight
Called in Module
Called in Speed
Also im Endeffekt ist das Hauptziel, dass die Methode OnUpdate() in den Klassen Flight und Speed ebenfalls ausgeführt werden. In dem Fall hilft mir leider kein HardCode mit Casting, da ich in die Liste unbegrenzt viele Module hinzufügen möchte.
https://stackoverflow.com/questions/12234097/how-to-cast-object-to-its-actual-type
Dann dürfte dir das helfen.
// reflection
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);
// interface
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction
foo.MyFunction();
// dynamic
dynamic d = obj; d.MyFunction();
Vergiss das bitte ganz schnell wieder, das ist Blödsinn
Was Du suchst ist eine Standard-Anforderung von der Objektorientierung
Ah, sorry. Da war ich nicht mit dem Kopf ganz da. Leider habe ich Virtual Overrides in C# noch nicht verwendet. Heißt das, dass diese auch bei aufrufen der Masterclass die jeweilige Methode mit der der Subclass ersetzen?
Das ist die Vererbung und Überschreibung von C#, bei Java geht's genauso, nur die Syntax ist hier und da etwas anders.
virtual heißt nur, dass die Methode überschrieben werden darf.
Bei Java darf jede Methode überschrieben werden und man muss das explizit verbieten.
Und das override ist bei Java genauso, nur eine andere Syntax. Da kann man auch die Basis-Implementierung aufrufen, heißt dann halt "super" und nicht "base".
Heißt das, dass diese auch bei aufrufen der Masterclass die jeweilige Methode mit der der Subclass ersetzen?
Bei Vererbung interessiert nicht, ob man die Basisklasse oder Ableitung hat, es zählt nur der Typ der Instanz. Und ob die Methode der Basis-Klasse auch aufgerufen wird, hängt von der Ableitung ab und wie sie das implementiert hat.
Deshalb war der Gedanke, dass wenn ich Module nutze, dass ich ja deren Methode verwenden würde. Aber wenn das als Ableitung automatisch in die korrekte Subclass abgeleitet wird, ist das gut zu wissen. :-)
Ah, dann habe ich natürlich daran vorbeigearbeitet. Problem war, dass ich nicht direkt verstanden habe, was der FS erreichen wollte, weil mich die Fragestellung etwas irritiert hat.