C# 无法转换类型`ObjectPool<;T>';至'ObjectPool<;ObjectPoolObject>';

C# 无法转换类型`ObjectPool<;T>';至'ObjectPool<;ObjectPoolObject>';,c#,generics,casting,C#,Generics,Casting,我有一个简单的ObjectPool实现。ObjectPool包含ObjectPoolObject的堆栈。ObjectPoolObject是定义两个方法的抽象类。我正在尝试向ObjectPoolObject类添加对父池的引用。我通过使用奇怪的循环模板模式开始工作,但是我无法从已经从ObjectPoolObject派生的类派生。(即,手榴弹继承自子弹,子弹继承自ObjectPoolObject) 总之,父池由ObjectPoolObject持有,如下所示:ObjectPool m_parent。。。

我有一个简单的ObjectPool实现。ObjectPool包含ObjectPoolObject的堆栈。ObjectPoolObject是定义两个方法的抽象类。我正在尝试向ObjectPoolObject类添加对父池的引用。我通过使用奇怪的循环模板模式开始工作,但是我无法从已经从ObjectPoolObject派生的类派生。(即,手榴弹继承自子弹,子弹继承自ObjectPoolObject)

总之,父池由ObjectPoolObject持有,如下所示:ObjectPool m_parent。。。但我似乎无法设定m_parent=这个;在ObjectPool类中。。。看来我肯定能做到。我不想强制转换到对象,然后再强制转换到对象池。。看来我应该可以安全地做到这一点:

public abstract class ObjectPoolObject : MonoBehaviour {
    public abstract void ObjectPool_Activate();
    public abstract void ObjectPool_Deactivate();

    public ObjectPool<ObjectPoolObject> m_pool;
}


public class ObjectPool<T> where T : ObjectPoolObject
{
    public ObjectPool(CreateObjectDelegate creationMethod)
    {
        m_creationMethod = creationMethod;
        T objectPoolObject = creationMethod();
        // this is the line that gives me error CS0030: Cannot convert type `ObjectPool<T>' to `ObjectPool<ObjectPoolObject>'
        objectPoolObject.m_pool = this;
    }
}
公共抽象类ObjectPoolObject:MonoBehavior{
公共抽象void ObjectPool_Activate();
公共抽象void ObjectPool_Deactivate();
公共对象池m_池;
}
公共类ObjectPool,其中T:ObjectPoolObject
{
公共对象池(CreateObjectDelegate creationMethod)
{
m_creationMethod=creationMethod;
T objectPoolObject=creationMethod();
//这一行给出了错误CS0030:无法将类型“ObjectPool”转换为“ObjectPool”
objectPoolObject.m_pool=这个;
}
}
因为T:ObjectPoolObject我应该可以这样做

我只需要ObjectPoolObject有一个对其父ObjectPool的引用。。。我怎样才能做到这一点

编辑:

这是错误消息:

error CS0030: Cannot convert type ObjectPool<T> to ObjectPool<ObjectPoolObject>'
错误CS0030:无法将类型ObjectPool转换为ObjectPool'
但由于T:ObjectPoolObject,它似乎应该能够做到这一点。它就像是说“无法将子类转换为父类…”T继承自ObjectPoolObject。。。因此,T的ObjectPool类似于ObjectPoolObject的子类ObjectPool。。。Liskov替换原则应该允许我将T的ObjectPool强制转换为ObjectPoolObject的ObjectPool

例如,我有一个项目符号的ObjectPool,其中项目符号继承自ObjectPoolObject。考虑到ObjectPool中的所有元素都是ObjectPoolObjects,我应该能够将其强制转换为ObjectPoolObjects的ObjectPool

编辑-我开始了解演员阵容的问题是什么。。。。很难解释,哇

EDIT2-使用泛型类型上的“in”关键字定义接口的答案是该问题的正确答案。然而!我认为这已经越过了“太复杂”的界限,并决定从ObjectPoolObject中删除m_pool字段。当您从对象池中获取对象时,由您记录它来自哪个池并将其适当地放回。m_pool字段只是把我的系统弄脏了太多,我无法证明包括它是合理的


从ObjectPool中完全删除泛型也是一种功能性解决方案,但它要求我强制转换每个ObjectPool.Get调用的返回结果,我决定我也不想这样做。

您需要查看C中的协方差和逆变换,如文档所示

简而言之,您需要将您的类声明为

public class ObjectPool<**in** T> where T : ObjectPoolObject
公共类ObjectPool,其中T:ObjectPoolObject

您需要查看C#中的协方差和逆变换,如文档所示

简而言之,您需要将您的类声明为

public class ObjectPool<**in** T> where T : ObjectPoolObject
公共类ObjectPool,其中T:ObjectPoolObject

问题在于,虽然T确实从ObjectPoolObject继承,但无论ObjectPool是否从ObjectPool继承,它都不做任何事情

例如,以以下代码为例:

public class Class1<T> where T : Class3, new()
{
    public Class1()
    {
        Class3 variable1;
        variable1 = new T(); // This works just fine T is or inherits from Class3

        Class1<Class3> variable3;
        variable3 = new Class1<Class2>(); // This will not work, while Class2 does indeed inherit from Class3,
                                          // Class1<Class2> is still a different class from Class1<Class3>
                                          // while their type parameters have an inheritance between them, they themselves do not.

        Class1<Class3> variable2;
        variable2 = new Class1<T>(); // And for just the same reason as stated above, this will not work either
    }
}
公共类Class1,其中T:Class3,new()
{
公共类别1()
{
第3类变量1;
variable1=new T();//只要T是或继承自Class3就可以了
1类变量3;
variable3=new Class1();//这将不起作用,而Class2确实继承自Class3,
//1班和1班仍然是一个不同的班
//虽然它们的类型参数之间有继承关系,但它们本身没有继承关系。
1类变量2;
variable2=new Class1();//出于与上述相同的原因,这也不起作用
}
}
要做你想做的事情,我们必须让事情变得更复杂(老实说,复杂并不总是一件好事)。但为了这个目的,请看一下:

public class AbstractObjectPool<T, T2> where T : AbstractObjectPool<T, T2> where T2 : ObjectPoolObject<T, T2>
{
    public T m_pool;
}

public class ObjectPool<T> : AbstractObjectPool<ObjectPool<T>, T> where T : ObjectPoolObject<ObjectPool<T>, T>
{
    public ObjectPool(Func<ObjectPool<T>> creationMethod)
    {
        ObjectPool<T> objectPoolObject = creationMethod();
        objectPoolObject.m_pool = this;
    }
}

public abstract class ObjectPoolObject<T, T2> where T : AbstractObjectPool<T, T2> where T2 : ObjectPoolObject<T, T2>
{

}
公共类AbstractObjectPool其中T:AbstractObjectPool其中T2:ObjectPoolObject
{
公共游泳池;
}
公共类ObjectPool:AbstractObjectPool,其中T:ObjectPoolObject
{
公共对象池(Func creationMethod)
{
ObjectPool objectPoolObject=creationMethod();
objectPoolObject.m_pool=这个;
}
}
公共抽象类ObjectPoolObject其中T:AbstractObjectPool其中T2:ObjectPoolObject
{
}
但是,我想知道(在您的情况下)对于一个简单的基类跳过泛型alltogeather和co是否会更好:

public class ObjectPool
{
    public ObjectPool(Func<ObjectPoolObject> creationMethod)
    {
        ObjectPoolObject objectPoolObject = creationMethod();
        objectPoolObject.m_pool = this;
    }
}

public abstract class ObjectPoolObject
{
    public ObjectPool m_pool;
}
公共类对象池
{
公共对象池(Func creationMethod)
{
ObjectPoolObject ObjectPoolObject=creationMethod();
objectPoolObject.m_pool=这个;
}
}
公共抽象类ObjectPoolObject
{
公共对象池m_池;
}

问题在于,虽然T确实从ObjectPoolObject继承,但无论ObjectPool是否从ObjectPool继承,它都不做任何事情

例如,以以下代码为例:

public class Class1<T> where T : Class3, new()
{
    public Class1()
    {
        Class3 variable1;
        variable1 = new T(); // This works just fine T is or inherits from Class3

        Class1<Class3> variable3;
        variable3 = new Class1<Class2>(); // This will not work, while Class2 does indeed inherit from Class3,
                                          // Class1<Class2> is still a different class from Class1<Class3>
                                          // while their type parameters have an inheritance between them, they themselves do not.

        Class1<Class3> variable2;
        variable2 = new Class1<T>(); // And for just the same reason as stated above, this will not work either
    }
}
公共类Class1,其中T:Class3,new()
{
公共类别1()
{
第3类变量1;
variable1=new T();//只要T是或继承自Class3就可以了
1类变量3;
variable3=new Class1();//这不起作用,而Class2确实起作用