首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法将类型`ObjectPool<T>“转换为`ObjectPool<ObjectPoolObject>”

无法将类型`ObjectPool<T>“转换为`ObjectPool<ObjectPoolObject>”
EN

Stack Overflow用户
提问于 2016-09-20 02:39:28
回答 3查看 174关注 0票数 0

我有一个简单的ObjectPool实现。ObjectPool包含一个ObjectPoolObjects堆栈。ObjectPoolObject是一个抽象类,它定义了两个方法。我正在尝试向ObjectPoolObject类添加对父池的引用。我开始使用奇怪的循环模板模式,但是我不能从已经从ObjectPoolObject派生的类中派生。(即,grenade继承自bullet,继承自ObjectPoolObject)...

无论如何,父池由ObjectPoolObject持有,如下所示: ObjectPool m_parent...但是我似乎不能在ObjectPool类中设置m_parent = this;看起来我绝对应该能做到。我不想先强制转换为object,然后再强制转换为ObjectPool。看起来我应该可以安全地做到这一点:

代码语言:javascript
复制
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;
    }
}

由于T: ObjectPoolObject,我应该能够做到这一点...

我所需要的就是让ObjectPoolObject引用它的父ObjectPool...我如何才能做到这一点呢?

编辑:

以下是错误消息:

代码语言:javascript
复制
error CS0030: Cannot convert type ObjectPool<T> to ObjectPool<ObjectPoolObject>'

但由于T: ObjectPoolObject,它似乎应该能够做到这一点。这就像是在说“无法将子类转换为父类...”T继承自ObjectPoolObject...因此,T的ObjectPool类似于ObjectPoolObject的子类ObjectPool ...利斯科夫替换原理应该允许我将T的ObjectPool转换为ObjectPoolObject的ObjectPool。

例如,我有一个Bullet的ObjectPool,其中Bullet继承自ObjectPoolObject。我应该能够将它转换为ObjectPoolObjects的ObjectPool,因为ObjectPool中的所有元素都是ObjectPoolObjects.....

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

EDIT2 -在泛型类型上使用"in“关键字定义接口是解决此问题的正确答案。然而!我已经决定这已经越过了“太复杂”的界限,并决定从ObjectPoolObject中删除m_pool字段。当您从对象池中获取一个对象时,由您来记录它来自哪个池并将其放回适当的位置。m_pool字段简直把我的系统弄得一团糟,我没有理由把它包括进来。

从ObjectPool中完全删除泛型也是一个函数式解决方案,但它需要我转换每个ObjectPool.Get调用的返回结果,我决定我也不想这样做。

EN

回答 3

Stack Overflow用户

发布于 2016-09-20 05:52:59

您需要使用in修饰符使您的类型参数变为逆变量,这只允许在接口和委托上使用。

代码语言:javascript
复制
interface IObjectPool<in T> where T : ObjectPoolObject
{

}

class ObjectPoolObject
{
    public IObjectPool<ObjectPoolObject> Pool { get; internal set; }
}

class ObjectPool<T> : IObjectPool<T> where T : ObjectPoolObject
{
    public ObjectPool(Func<T> createObject)
    {
        T obj = createObject();
        obj.Pool = this;
    }
}
票数 3
EN

Stack Overflow用户

发布于 2016-09-20 03:42:32

您需要将C#中的协方差和逆方差视为文档化的here

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

代码语言:javascript
复制
public class ObjectPool<**in** T> where T : ObjectPoolObject
票数 2
EN

Stack Overflow用户

发布于 2016-09-20 03:55:12

问题是,虽然T确实继承了ObjectPoolObject,但无论ObjectPool是从ObjectPool继承的,它都与此无关。

例如,使用以下代码:

代码语言:javascript
复制
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
    }
}

要做你想做的事情,我们必须让事情变得更复杂(老实说,复杂性并不总是一件好事)。但是,为了方便起见,我们来看看这个:

代码语言:javascript
复制
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>
{

}

然而,我想知道(在您的情况下)跳过泛型的所有集合和co来创建一个简单的基类会不会更好:

代码语言:javascript
复制
public class ObjectPool
{
    public ObjectPool(Func<ObjectPoolObject> creationMethod)
    {
        ObjectPoolObject objectPoolObject = creationMethod();
        objectPoolObject.m_pool = this;
    }
}

public abstract class ObjectPoolObject
{
    public ObjectPool m_pool;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39579969

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档