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

如何优化C#泛型使用,避免游戏属性系统重复类型声明?

优化游戏属性系统的C#泛型重复声明问题

你当前的属性系统设计中,RuntimeStat<T,Z>需要重复声明属性类和值类型(比如RuntimeStat<AttackPower, float>),确实存在冗余——因为AttackPower已经明确继承自Stat<float>,值类型可以被自动推断。以下是两种可行的优化方案:

方案1:静态工厂方法实现类型推断

通过添加静态工厂方法,让C#编译器自动推断泛型类型,无需手动重复声明值类型。这是保留类型安全前提下的最优方案。

修改RuntimeStat类

给RuntimeStat<T,Z>添加静态创建方法:

public class RuntimeStat<T, Z> where T : Stat<Z>
{
    public int Level { get; private set; }
    public T Stat { get; }
    public Z Value => Stat.GetStat(Level);

    public RuntimeStat(T stat)
    {
        Stat = stat;
    }

    public void LevelUp()
    {
        Level++;
    }

    // 静态工厂方法,用于自动推断泛型类型
    public static RuntimeStat<T, Z> Create(T stat)
    {
        return new RuntimeStat<T, Z>(stat);
    }
}

或者创建独立的静态工厂类(调用更简洁):

public static class RuntimeStatFactory
{
    public static RuntimeStat<T, Z> Create<T, Z>(T stat) where T : Stat<Z>
    {
        return new RuntimeStat<T, Z>(stat);
    }
}

角色类中的简化使用

无论用哪种方式,创建实例时都可以省略泛型参数声明:

public class SomeCharacterClass
{
    private RuntimeStat<AttackPower, float> _attackPower;

    public SomeCharacterClass()
    {
        // 方式1:使用RuntimeStat自身的静态方法
        _attackPower = RuntimeStat<AttackPower, float>.Create(new AttackPower());
        
        // 方式2:使用独立工厂类(更简洁)
        _attackPower = RuntimeStatFactory.Create(new AttackPower());
    }

    public void Attack()
    {
        Debug.Log($"Attack for {_attackPower.Value} damage!");
    }
}

方案2:重构RuntimeStat为单泛型参数

如果希望彻底移除双泛型参数,可以通过非泛型接口+类型转换实现,但会牺牲一点类型安全(需要手动指定值类型)。

定义非泛型接口并修改Stat基类

// 非泛型接口,提供基础属性获取方法
public interface IStat
{
    object GetStatValue(int level);
}

// 泛型Stat基类实现非泛型接口
public abstract class Stat<T> : IStat
{
    public abstract T GetStat(int level);

    object IStat.GetStatValue(int level)
    {
        return GetStat(level);
    }
}

重构RuntimeStat为单泛型参数

public class RuntimeStat<T> where T : IStat
{
    public int Level { get; private set; }
    public T Stat { get; }

    public RuntimeStat(T stat)
    {
        Stat = stat;
    }

    public void LevelUp()
    {
        Level++;
    }

    // 泛型方法获取强类型属性值
    public Z GetValue<Z>()
    {
        return (Z)Stat.GetStatValue(Level);
    }
}

角色类中的使用

public class SomeCharacterClass
{
    private RuntimeStat<AttackPower> _attackPower;

    public SomeCharacterClass()
    {
        _attackPower = new RuntimeStat<AttackPower>(new AttackPower());
    }

    public void Attack()
    {
        // 需要手动指定值类型
        float damage = _attackPower.GetValue<float>();
        Debug.Log($"Attack for {damage} damage!");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:39:36