首页 > 解决方案 > 如何将实例的引用从具有约束参数类型的类传递给该约束类型的实例?

问题描述

假设我有这两个类:

public abstract class ASpawnedObject {}
public abstract class ASpawner<T> where T : ASpawnedObject {}

该类ASpawner创建了一些ASpawnedObject实例。我希望它将自身传递给ASpawnedObject构造函数并将其引用作为成员变量:

public abstract class ASpawnedObject {}
{
    ASpawner<ASpawnedObject> spawner;

    public void Init(ASpawner<ASpawnedObject> spawner)
    {
        this.spawner = spawner;
    }
}
public abstract class ASpawner<T> where T : ASpawnedObject
{
    public void Spawn()
    {
        T spawnedObject = System.Activator.CreateInstance<T>();
        spawnedObject.Init(this);
    }
}

但是:spawnedObject.Init(this)导致ASpawner. 即使有类型约束,它也无法转换ASpawner<T>为。ASpawner<ASpawnedObject>我不明白。它不遵循多态性原则吗?

标签: c#generics

解决方案


这个测试类编译运行没有任何异常

[TestClass]
public class Test
{
    [TestMethod]
    public void X()
    {
        var ghostSpawner = new GhostSpawner();
        ghostSpawner.Spawn();
    }
}

您需要做的是根据您的生成对象来约束您的生成器和生成的对象。是的,就后者而言,这意味着:

public abstract class ASpawnedObject<T> where T : ASpawnedObject<T>
{
    ASpawner<T> spawner;
    public void Init(ASpawner<T> spawner) => this.spawner = spawner;
}

public abstract class ASpawner<T> where T : ASpawnedObject<T>
{
    public void Spawn()
    {
        T spawnedObject = Activator.CreateInstance<T>();
        spawnedObject.Init(this);
    }
}

如您所见,这意味着ASpawnedObject基类必须是通用的。然后,您可以创建使测试通过的非泛型具体类。

public class GhostSpawner : ASpawner<Ghost>
{}

public class Ghost : ASpawnedObject<Ghost>
{}

推荐阅读