You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让泛型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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:27:04