将对象实例转换为实际类型

时间:2017-01-14 01:09:00

标签: c# inheritance unity3d dynamic casting

我发送了几种不同类型的package类,我通过网络对其进行序列化和发送。所有包都扩展了AbstractPackage

public abstract class AbstactPackage() {}

public class UpdatePackage : AbstractPackage {
    public float x, y, rot;

    public UpdatePackage(float pX, float pY, float pRot) {
        x = pX; y = pY; rot = pRot;
    }
}

在另一台计算机上收到包后,它被序列化为一个abstractPackage实例并调用readResponse。但是现在我需要确定这个实例的确切类型(例如UpdatePackage)

private void readResponse(AbstractPackage p) {
    if(p is UpdatePackage) readResponse(p as UpdatePackage);
}

private void readResponse(UpdatePackage p) { ... }

目前,我在readResponse函数中有30个不同的if语句,用于我拥有的每种类型的包。有没有办法可以更动态地做到这一点?

我无法使用dynamic关键字,因为我使用的是Unity,它使用旧的dotNet版本。

1 个答案:

答案 0 :(得分:4)

当您收到该类型的包时,您可以使用从类型到委托的字典。例如:

class PackageReader
{
    private static readonly Dictionary<Type, Action<AbstractPackage>> responseReaders;

    static PackageReader()
    {
        responseReaders = new Dictionary<Type, Delegate>();
        RegisterReader<UpdatePackage>(ReadUpdatePackage);
        RegisterReader<DownloadPackage>(ReadDownloadPackage);
        ...
    }

    private static void RegisterReader<T>(Action<T> reader)
    {
        Action<AbstractPackage> d = package => reader((T) package);
        responseReaders.Add(typeof(T), d);
    }

    private static void ReadResponse(AbstractPackage p)
    {
        responseReaders[p.GetType()].Invoke(p);
    }

    private static void ReadUpdatePackage(UpdatePackage p) { ... }
    private static void ReadDownloadPackage(DownloadPackage p) { ... }
    ...
}

(我已经使每个&#34;阅读&#34;方法有不同的名称,以便方法组转换明确无误。)