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

C#如何声明泛型参数未知的抽象类类型属性

方案评估:dynamic不是最优选择

使用dynamic的弊端非常明显:

  • 丢失编译期类型校验,所有成员调用的错误都会推迟到运行时才暴露,排查成本极高
  • 运行时需要做类型解析,性能比静态类型调用低3~10倍,对于状态效果这类高频调用的逻辑会有明显的性能开销
  • 无法适配你基类BaseModel<T>的序列化逻辑,dynamic类型的序列化、反序列化需要额外做大量适配工作

最优解决方案:提取非泛型公共接口/抽象基类

你当前的核心问题是泛型类StatusEffectLogicModel<T>没有非泛型的上层抽象,导致无法声明不绑定具体泛型参数的变量。只需要提取所有状态效果的公共成员到非泛型接口即可:

// 第一步:定义所有状态效果的公共行为接口
public interface IStatusEffectLogic
{
    // 把你需要对外调用的所有公共方法、属性都定义在这里
    // 例如状态生效、移除、每帧/每回合触发的逻辑
    void OnApply(CharacterModel owner);
    void OnRemove(CharacterModel owner);
    void OnTick(int deltaTime);
    int Duration { get; }
}

// 第二步:让原泛型基类实现该接口
// 注意:你原代码里继承BaseModel时缺了一个闭合尖括号,这里一并修正
public abstract class StatusEffectLogicModel<T> : BaseModel<StatusEffectLogicModel<T>>, IStatusEffectLogic
{
    // 原有委托、事件逻辑不变
    // 实现IStatusEffectLogic中定义的公共成员即可
    public abstract void OnApply(CharacterModel owner);
    public abstract void OnRemove(CharacterModel owner);
    public abstract void OnTick(int deltaTime);
    public abstract int Duration { get; }
}

// 第三步:CharacterModel中直接用接口声明属性
public class CharacterModel : BaseModel<CharacterModel> {
    public IStatusEffectLogic activeStatusEffect;
}

这个方案完全保留了静态类型的所有优势,编译期可检查类型错误,性能无额外损耗,也能兼容你原有的序列化逻辑。

其他可选方案

如果有少数场景需要访问具体子类的特有成员,可以配合模式匹配做类型转换:

if (activeStatusEffect is TauntStatusEffectLogic tauntEffect)
{
    // 直接操作Taunt效果特有的成员
    tauntEffect.ForceTarget = selectedEnemy;
}

如果你的公共逻辑存在返回泛型类型的需求,可以使用协变泛型接口:

public interface IStatusEffectLogic<out TConfig>
{
    TConfig GetConfig();
}

内容的提问来源于stack exchange,提问作者Bill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:42:04