2013-04-18 8 views
14

Ich habe einige ähnliche Fragen dazu gelesen, aber keine scheint das Problem zu lösen, vor dem ich stehe. Die typische Antwort ist die Umwandlung in die abgeleitete Klasse, aber ich kann das nicht, da ich den abgeleiteten Klassentyp nicht kenne.Wie rufe ich eine abgeleitete Klassenmethode aus der Basisklasse auf?

Hier ist mein Beispiel:

class WireLessDevice { // base class 
    void websocket.parsemessage(); // inserts data into the wireless device object 
} 

class WiFi : WireLessDevice { // derived class 
    GPSLoc Loc; 
} 

Wireless-Gerät kann auch weiß, dass ich nicht machen Bluetooth, Wi-Max, Cellular, usw. Geräte und somit abgeleitet werden, welche Art von wirelessdevice die Daten zu empfangen werden .

Wenn ein GPS-Paket auf dem Websocket in der Basisklasse empfangen wird, muss ich den Standort des abgeleiteten Geräts aktualisieren.

Ich dachte vielleicht, eine Nachricht über eine Warteschlange zu senden oder einen Event-Handler zu erstellen und die Position in den Event-Argumenten zu senden, aber diese erscheinen etwas klobig, wenn die Daten in der Klasse bleiben.

Ist etwas in die Sprache eingebaut, das es mir erlauben würde, mein abgeleitetes Gerät von der Basisklasse anzurufen, ohne den Typ zu kennen?

+0

Werfen Sie einen Blick auf Dekoration Muster. Ihr Problem scheint Ihr falsches Design zu sein. –

+4

Keine Notwendigkeit für einen Dekorator ... Werfen Sie einen Blick auf abstrakte oder virtuelle Methoden ... – Crisfole

Antwort

31

Der richtige Weg ist das Hinzufügen einer Methode DoSomeMagic() in der Basisklasse, mit Standardimplementierung oder Zusammenfassung. Die abgeleitete Klasse sollte sie dann überschreiben, um ihre Magie zu tun.

So etwas wie dies vielleicht:

public class WireLessDevice 
{ // base class 
    protected virtual void ParseMessage() 
    { 
     // Do common stuff in here 
    } 
} 

public class WiFi : WireLessDevice 
{ // derived class 
    override void ParseMessage() 
    { 
     base.ParseMessage();//Call this if you need some operations from base impl. 
     DoGPSStuff(); 
    } 
    private void DoGPSStuff() 
    { 
     //some gps stuff 
    } 
    GPSLoc Loc; 
} 
+4

+1 für Magic ... – CSharpie

+0

Also wenn ich this.setGPSLocation von der Basisklasse websocket.parsemessage() aufrufen wird es automatisch aufrufen abgeleitete Klasse 'setGPSLocation? – CramerTV

+0

Ich würde SetGPSLocation nicht von der Basisklasse, sondern in der abgeleiteten Klasse aufrufen. Wird meine Antwort aktualisieren, um zu demonstrieren. –

2

Virtual methods wäre eine gute Lösung sein. Sie erstellen in der Basisklasse eine Methode ParseMessage, die alle für jeden abgeleiteten Typ gemeinsamen Komponenten behandelt und dann für bestimmte Geräte überschreibt.

Um noch in der Lage sein, andere Nachrichtentypen zu handhaben, müssen Sie die base.ParseMessage gegebenenfalls nennen:

class WireLessDevice 
{ 
    protected virtual bool ParseMessage(byte[] message) 
    { 
     // Inspect message and handle the known ones 
     return true; // Only if message parsed, otherwise false 
    } 
} 

class WiFi : WireLessDevice 
{ 
    GPSLoc Loc; 

    protected override bool ParseMessage(byte[] message)  
    { 
     bool messageParsed = base.ParseMessage(message) 
     if (!messageParsed) 
     { 
      // Handle device specific message with GPSLoc 
      Loc = ... 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

Wenn Ihre Basisklasse ist nicht alle anderen Nachrichten Handhabung könnte der Code einfacher sein (und unter Verwendung abstract). In diesem Fall würde ich jedoch in Erwägung ziehen, den Web-Socket-Code in die abgeleitete Klasse zu verschieben.

+1

Diese Lösung ist Omers ähnlich und ich glaube, dass es für mich funktioniert. Ich werde es versuchen und die Antworten aktualisieren. Danke Thorarin! – CramerTV

+0

@CramerTV Das bekommst du, wenn du antwortest, während jemand seinen Post bearbeitet, aber ja, es ist fast identisch. Ich mochte meine Erklärung besser, also behielt ich die Antwort. – Thorarin

+0

Das hat super funktioniert Thorarin. Ich habe Ihren Rückgabewert als aufgezählten Typ geändert, bei dem GPS einer der Werte war. Auf diese Weise würde die parseMessage-Routine einen Wert zurückgeben, der angibt, welche Art von Nachricht empfangen wurde, und ich aktualisiere nur den Ort, wenn die zu analysierende Nachricht den GPS-Koordinaten entsprach (ich kann andere 'Sonderfall'-Nachrichten haben, die ich später bearbeiten muss) .) Ich habe auch einen "Fehler" -Typ in die Aufzählung aufgenommen, so dass ich einen Fehler wie das obige Beispiel erkennen konnte. Danke für deine Antwort. Ich habe Sie beide hochgestuft, aber ich habe Omers Antwort gewählt, nur weil er der Erste war. – CramerTV