gpt4 book ai didi

c# - 继承与类型转换

转载 作者:太空宇宙 更新时间:2023-11-03 17:18:40 25 4
gpt4 key购买 nike

我在将继承类型转换为基类时遇到了一个基本问题。我知道这通常是不可能的,也就是说,您可以将派生类转换为其基类,但反之则不然。这是我正在苦苦挣扎的示例片段:

假设我定义了一个抽象类来表示计算机 PCI 卡:

public abstract class PciDevice
{
public abstract int GetDeviceId();
public abstract String GetVendorName();
}

现在我创建了 3 种类型的继承类(设备):

public class GraphicsCard : PciDevice
{
public override int GetDeviceId() { return 1666; }
public override String GetVendorName() { return "CoolCorp"; }

int trianglesPerSecond;
ChipsetTypeEnum chipsetType;
}

public class AudioCard : PciDevice
{
public override int GetDeviceId() { return 1999; }
public override String GetVendorName() { return "ShinyCorp"; }

int numChannels;
int samplingRate;
}

public class Modem : PciDevice
{
public override int GetDeviceId() { return 1234; }
public override String GetVendorName() { return "BoringCorp"; }

public int baudRate;
bool faxEnabled;
}

现在,我在计算机内部定义了一个“插槽”:

public class PciCardSlot
{
private int slotId;
private int clockFreq;
private PciDevice cardInSlot;

public PciDevice getCard() { return cardInSlot; }

public void setCard(PciDevice card) { cardInSlot = card; }
}

我有一个插槽数组来表示计算机中的所有插槽:

PciCardSlot [] pciSlotsInComputer = new PciCardSlot[6];

然后,我定义一个函数来检索 PciDevice 对象,给定一个插槽 ID:

public PciDevice getInsertedCard(int slotId)
{
return pciSlotsInComputer[slotId].getCard();
}

到目前为止一切顺利。现在,在代码的某处,我实例化了 AudioCard、GraphicsCard 和 Modem 对象并将它们分配给插槽。

AudioCard a = new AudioCard();
Modem b = new Modem();
GraphicsCard c = new GraphicsCard();
PciCardSlot s0 = new PciCardSlot(); s0.setCard(a);
PciCardSlot s1 = new PciCardSlot(); s1.setCard(b);
PciCardSlot s2 = new PciCardSlot(); s2.setCard(c);
pciSlotsInComputer[0] = s0; pciSlotsInComputer[1] = s1; pciSlotsInComputer[2] = s2;

然后,我有一个如下所示的函数,它旨在对调制解调器对象进行操作:

public setBaudRateForModem(int slotId, int rate)
{
((Modem)getInsertedCard(slotId)).baudRate = rate; // Can not cast!!!
}
...
// I know that slot 1 contains a modem, so I do:
setBaudRateForModem(1, 9600);

上面的转换不起作用,因为我试图从 PciDevice 对象转换为从 PciDevice 派生的调制解调器对象。

我一直在阅读这方面的内容,几乎在我看到的所有地方,人们似乎都认为,如果您需要将基类强制转换为成员类,那么您的设计就很糟糕。我的类(class)层次结构设计不好吗?有什么建议么?感谢阅读。

最佳答案

好吧,我不认为以多态方式处理 PciDevices 存在内在问题。框架中内置了许多实例,需要将对象转换回“上下文已知”类型。

但是,BaudRate 是调制解调器独有的属性,因此它的定义和逻辑应该位于该类中。不应该有具有该特定目的的更高级别的功能。

一般来说,您的 get 函数应该是获取所属对象属性的定义。

本质上,在尝试访问波特率之前,您需要知道调制解调器的位置。

例如,如果您想更新所有调制解调器的波特率并且调制解调器类封装得很好,您应该能够执行类似的操作

void UpdateModemBaudRates(int baudRate)
{
foreach(PciCardSlot slot in pciSlotsInComputer)
{
Modem modem = slot.CardInSlot as Modem;
if(modem != null)
{
modem.BaudRate = baudRate
}
}
}

如果这很难理解,请查找 asis 关键字。

当然,Linq 有一种更现代的方式来执行此操作,这是受 Chris 评论启发的一种方式。

void UpdateModemBaudRates(int baudRate)
{
pciSlotsInComputer.Select(s => s.CardInSlot).OfType<Modem>().AsParallel().ForAll<Modem>(modem => modem.BaudRate=baudRate);
}

关于c# - 继承与类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5595699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com