数组中的不同类型,如何知道在将它们从数组中取出时将它们强制转换为什么

本文关键字:数组 为什么 转换 何知道 同类型 | 更新日期: 2023-09-27 18:00:34

假设一个类型为Packet的通用List,包含扩展PacketoginPacketChatPacket

假设我把这些放在一个列表中。当我取出它们时,每种最"特定"的类型都是数据包。不过,我想把它们转换成更具体的类型,回到它们原来的LoginPacketChatPacket

问题:我该怎么做?

参考:如何在运行时以编程方式强制转换对象?

所以。。。似乎如果这些自定义类共享一个公共接口,就可以解决强制转换问题了?但如果是这样的话,我的类就不能共享一个接口。我需要在接口上构建接口,在类上构建类。那么…我该怎么做呢?如果这个问题不那么准确,我很抱歉。不知道如何表达我的确切问题。

数组中的不同类型,如何知道在将它们从数组中取出时将它们强制转换为什么

可以有一个完整的if/else或开关的长列表

if (item is ChatPacket)
{
    // cast
}
else if (...)
{
    // cast
}
else ...

然而,这可能会变得难以处理。

您可能希望重新审视您的课堂设计。通过拥有List<Packet>,您实际上是在声明您不关心派生子级之间的差异,至少在它们独特的API方面是这样。

换句话说,如果你的设计是

class Packet { public void Foo() { } }
class ChatPacket : Packet { public void Bar() { } }

你是说你只关心能够访问Foo()

如果你确实关心差异,也许你可以通过抽象或虚拟方法在基础上表达这些差异,并在儿童中表达过度行为。因此,您仍然有一个基类集合,但您仍然可以获得每个子级指定的自定义行为。

class Packet { public virtual void Foo() { } }
class ChatPacket : Packet { public override void Foo() { } }

在这里,您只需呼叫Foo()即可。无需铸造。

您可以这样做:

if (myPacket is LoginPacket) {
    // Do LoginPacket stuff
}
else if (myPacket is ChatPacket) {
    // Do ChatPacket stuff
}

一旦你知道它是否是正确的类型,你就可以使用as关键字进行投射

ProcessLoginPacket(myPacket as LoginPacket);