C#是否支持类似Java的原始类型?对象池泛型类型转换报错如何解决
解决方案
C# 没有Java那种基于类型擦除实现的泛型原始类型,你可以通过以下两种常用方案解决你的场景问题:
方案1:引入非泛型池接口(推荐,灵活度高)
这个方案和你Java里用原始类型的效果一致,同时保留了类型安全校验:
- 定义非泛型的
IPool接口,提取公共的释放方法:
public interface IPool { void Free(IPoolable obj); }
- 让你的泛型
Pool<T>类实现该接口:
public abstract class Pool<T> : IPool where T : IPoolable { // 原有所有代码保持不变,新增接口实现: void IPool.Free(IPoolable obj) { Free((T)obj); // 由于你所有池对象都是通过对应类型的Pool获取的,此处转换100%安全 } }
- 修改
MyObject中的池字段类型为非泛型接口:
public abstract class MyObject : IPoolable { // 把原来的Pool<MyObject>改成IPool即可 public IPool pool; // 其余原有代码(CallMe、Act、ToPool、Reset)全部不需要改动 }
修改完成后ObjectFactory中的obj.pool = pool赋值就不会再报类型错误,所有原有逻辑都可以正常运行。
方案2:使用递归泛型基类(类型更严格)
如果你需要在派生类中直接拿到对应类型的泛型池引用,可以把基类改成递归泛型定义:
// 泛型基类定义 public abstract class MyObject<T> : IPoolable where T : MyObject<T> { public Pool<T> pool; public void CallMe() { if (Act()) { ToPool(); } } public abstract bool Act(); public void ToPool() { pool.Free((T)this); pool = null; } public abstract void Reset(); } // 派生类实现 public class MovableObject : MyObject<MovableObject> { public override bool Act() { return true; } public override void Reset() { } public override string ToString() { return "Movable"; } }
这个方案下所有池引用都是严格对应派生类类型的,不存在类型转换风险,同时ObjectFactory的创建逻辑不需要做任何修改即可正常运行。
内容的提问来源于stack exchange,提问作者V.Lap
相关产品推荐
相关产品推荐

