【发布时间】:2011-05-07 22:14:04
【问题描述】:
我有一个对象池,每当我对池中的对象调用 Free() 时,我都需要调用委托方法 OnFree()。
Free() 是在外部创建的,并在创建池时设置在对象上。 OnFree 因对象而异,有时甚至为 null。
池中的对象继承自 Poolable 类。
class Poolable
{
public Action Free();
public Action OnFree();
}
目前我通过这样做在继承类中创建 OnFree:
class Light
{
public Light()
{
// Create method to be called when Free() is called on this light.
OnFree = () =>
{
DoStuffHere();
};
}
}
但是,这将为每个灯光创建一个单独的委托,这会浪费大量内存,尤其是当池中有数万个对象时。呃,每次调用这个构造函数时都会创建一个新的委托,对吧?
什么是允许对象创建自己的 OnFree() 委托的好方法,以便每个对象类型只有一个委托,而不是每个实例一个委托?
我当然能想到一种方法,但我希望有人能想到一种“好”的方法——一种易于维护的方法。
编辑:我可以在基类中将 OnFree() 委托设为静态,以便它以某种方式对每个继承的类型都是静态的吗?
编辑:澄清如何使用 Pool,以及为什么 Free() 是委托,而不是虚拟方法。如果您能想到更好的方法,请告诉我。
public class Pool<T> where T : Poolable
{
private int _liveCount;
private T[] _pool;
[...]
public Pool(int capacity, Func<T> allocateFunction)
{
[...]
// Fill pool with initial items:
for (int i = 0; i < capacity; i++)
{
T item = _allocate();
item.Free = () => Free(item);
_pool[i] = item;
}
}
/// <summary>
/// Frees given object from this pool. Object is assumed to
/// be in this pool.
/// </summary>
public void Free(Poolable obj)
{
obj.OnFree();
_liveCount -= 1;
[...]
}
}
【问题讨论】:
-
我试图让问题保持简单,但我发现很难问清楚 -- 所以如果我遗漏了任何信息或有任何不清楚的地方,请提出问题。
-
IIRC,Lambda 表达式被转换为匿名委托,而匿名委托又被实现为编译器生成的类的方法。所以你只得到一种方法。唯一使用的内存是函数指针的内存。
-
艾蒂安:这意味着什么?这是否意味着即使我多次调用构造函数也只创建一种方法?
-
艾蒂安,谢谢,我希望你是对的。一些确认会很好,因为我想不出一种快速的方法来测试它。