如何让泛型ActorController的所有子类共享唯一的Selection静态属性
问题根因
这是C#泛型的固有设计特性:泛型类的静态成员会按每个闭合构造类型独立存储,ActorController<Creature>和ActorController<Hero>在运行时是完全独立的两个类型,因此各自的Selection属性完全隔离,不会互通,并非代码逻辑BUG。
解决方案
方案1:新增非泛型基类存储共享静态属性(最推荐)
- 新增无泛型参数的抽象基类
ActorController,继承MonoBehaviour,将全局共享的Selection静态属性定义在该基类中 - 原泛型类
ActorController<T>改为继承这个非泛型基类,保留T:Character的约束即可 - 原有
Select方法直接操作基类的静态Selection属性,不需要修改子类实现
代码示例:
// 新增非泛型基类,存储全局共享状态 public abstract class ActorController : MonoBehaviour { public static ActorController Selection { get; protected set; } } // 原泛型类调整继承关系 public abstract class ActorController<T> : ActorController where T : Character { public void Select() { // 直接赋值给基类的全局静态属性,所有子类共享 Selection = this; // 其余原有逻辑保持不变 } // 可选:新增辅助属性直接拿到泛型类型的选中对象 public static T SelectedAsT => Selection as T; }
该方案对原有代码侵入性极低,不需要调整子类的继承逻辑,同时保留了泛型类的所有特性。
方案2:独立静态类存储全局选中状态
如果不想修改现有基类的继承结构,可以单独定义非泛型静态类托管全局选中状态:
// 独立的全局选中状态管理类 public static class SelectionManager { public static ActorController CurrentSelection { get; set; } } // 泛型类调整Selection属性的实现 public abstract class ActorController<T> : MonoBehaviour where T : Character { public static ActorController Selection { get => SelectionManager.CurrentSelection; protected set => SelectionManager.CurrentSelection = value; } public void Select() { Selection = this; } }
该方案将全局状态和业务类解耦,适合后续需要扩展选中相关逻辑(如选中事件广播、多选支持)的场景。
注意事项
- 需要判断选中对象类型时,直接用
is关键字做类型匹配即可:if (Selection is HeroController hero) { // 英雄专属选中逻辑 } - 不建议用静态构造函数同步不同泛型参数类的静态属性,会增加不必要的复杂度,还容易引发线程安全问题。
内容的提问来源于stack exchange,提问作者McGregor777
相关产品推荐
相关产品推荐

