22

我已经阅读了几个类似的问题,但似乎没有一个可以解决我面临的问题。典型的答案是强制转换为派生类,但我不能,因为我不知道派生类的类型。

这是我的例子:

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

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

无线设备也可以派生为蓝牙、Wi-Max、蜂窝等设备,因此我不知道哪种类型的无线设备将接收数据。

当在基类的 websocket 上收到 GPS 数据包时,我需要更新派生设备的位置。

我想也许可以通过队列发送消息或创建事件处理程序并在事件参数中发送位置,但是当数据保留在类中时,这些似乎有点笨拙。

语言中是否有内置的东西可以让我在不知道类型的情况下从基类调用派生设备?

4

2 回答 2

39

正确的方法是在基类中添加一个方法 DoSomeMagic() ,默认实现,或者抽象。派生类应该重写它来发挥它的魔力。

可能是这样的:

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;
}
于 2013-04-18T16:51:54.647 回答
3

虚拟方法将是一个很好的解决方案。您在基类中创建一个方法,该方法ParseMessage处理每个派生类型共有的所有内容,然后覆盖特定设备。

为了仍然能够处理其他消息类型,您需要根据需要调用 base.ParseMessage

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;
        }
    }
}

如果您的基类不处理任何其他消息,则代码可能会更简单(并且使用abstract)。但是,在这种情况下,我会考虑将 Web 套接字代码移至派生类。

于 2013-04-18T17:02:56.857 回答