我有一个简单的ObjectPool实现。ObjectPool包含一个ObjectPoolObjects堆栈。ObjectPoolObject是一个抽象类,它定义了两个方法。我正在尝试向ObjectPoolObject类添加对父池的引用。我开始使用奇怪的循环模板模式,但是我不能从已经从ObjectPoolObject派生的类中派生。(即,grenade继承自bullet,继承自ObjectPoolObject)...
无论如何,父池由ObjectPoolObject持有,如下所示: ObjectPool m_parent...但是我似乎不能在ObjectPool类中设置m_parent = this;看起来我绝对应该能做到。我不想先强制转换为object,然后再强制转换为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;
}
}由于T: ObjectPoolObject,我应该能够做到这一点...
我所需要的就是让ObjectPoolObject引用它的父ObjectPool...我如何才能做到这一点呢?
编辑:
以下是错误消息:
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调用的返回结果,我决定我也不想这样做。
发布于 2016-09-20 05:52:59
您需要使用in修饰符使您的类型参数变为逆变量,这只允许在接口和委托上使用。
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;
}
}发布于 2016-09-20 03:42:32
您需要将C#中的协方差和逆方差视为文档化的here。
简而言之,您需要将您的类声明为
public class ObjectPool<**in** T> where T : ObjectPoolObject发布于 2016-09-20 03:55:12
问题是,虽然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
}
}要做你想做的事情,我们必须让事情变得更复杂(老实说,复杂性并不总是一件好事)。但是,为了方便起见,我们来看看这个:
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来创建一个简单的基类会不会更好:
public class ObjectPool
{
public ObjectPool(Func<ObjectPoolObject> creationMethod)
{
ObjectPoolObject objectPoolObject = creationMethod();
objectPoolObject.m_pool = this;
}
}
public abstract class ObjectPoolObject
{
public ObjectPool m_pool;
}https://stackoverflow.com/questions/39579969
复制相似问题