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

重载PlayerSkillsClass运算符引发StackOverflowException问题求助

解决思路与实现方案

一、先搞定StackOverflowException的问题

你遇到的栈溢出,百分百是因为运算符重载代码里自己调用了自己,陷入无限循环了。比如你可能写了这种坑人的代码:

public static PlayerSkillsClass operator +(PlayerSkillsClass a, float b)
{
    // 错在这:这里又调用了+运算符,等于无限套娃
    return a + b;
}

这种写法会让方法反复调用自己,直到栈内存被撑爆,直接报错。

二、通用属性运算实现(不用逐个写属性逻辑)

既然后续要加很多技能属性,就别一个个写运算代码了,用反射遍历所有数值属性来统一处理,新增属性时完全不用改运算逻辑。

1. 核心思路

  • 用反射找出类里所有float、int类型的公开属性
  • 运算时挨个遍历这些属性,执行对应的加减操作
  • 运算返回新的实例,别改原对象,避免莫名其妙的bug

2. 完整代码示例

using System;
using System.Linq;
using System.Reflection;

public class PlayerSkillsClass
{
    public float Speed { get; set; }
    public float Agility { get; set; }
    public float Jump { get; set; }
    public float Strength { get; set; }
    // 以后加新属性比如Stamina,直接加就行,不用改下面的运算代码

    // 提前缓存所有数值属性,避免每次运算都反射(优化性能)
    private static readonly PropertyInfo[] _skillProperties;

    static PlayerSkillsClass()
    {
        // 只筛选float和int类型的公开实例属性
        _skillProperties = typeof(PlayerSkillsClass)
            .GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => p.PropertyType == typeof(float) || p.PropertyType == typeof(int))
            .ToArray();
    }

    // 重载 +:技能实例 + 数值(给所有属性加同一个值)
    public static PlayerSkillsClass operator +(PlayerSkillsClass skills, float value)
    {
        var newSkills = new PlayerSkillsClass();
        foreach (var prop in _skillProperties)
        {
            float currentVal = Convert.ToSingle(prop.GetValue(skills));
            prop.SetValue(newSkills, currentVal + value);
        }
        return newSkills;
    }

    // 重载 +:技能实例 + 技能实例(对应属性相加)
    public static PlayerSkillsClass operator +(PlayerSkillsClass a, PlayerSkillsClass b)
    {
        var newSkills = new PlayerSkillsClass();
        foreach (var prop in _skillProperties)
        {
            float valA = Convert.ToSingle(prop.GetValue(a));
            float valB = Convert.ToSingle(prop.GetValue(b));
            prop.SetValue(newSkills, valA + valB);
        }
        return newSkills;
    }

    // 可选:重载 += 运算符,直接复用上面的+逻辑
    public static PlayerSkillsClass operator +=(PlayerSkillsClass skills, float value)
    {
        skills = skills + value;
        return skills;
    }

    public static PlayerSkillsClass operator +=(PlayerSkillsClass a, PlayerSkillsClass b)
    {
        a = a + b;
        return a;
    }
}

3. 代码说明

  • 自动适配新属性:以后加新的技能属性(比如Stamina),只要是float/int类型,自动会被纳入运算逻辑,不用改任何重载代码
  • 避免递归:运算符重载里直接操作属性值,不再调用自身的+运算符,彻底解决栈溢出
  • 缓存属性:静态构造函数里提前把要运算的属性缓存好,避免每次运算都反射,提升性能

三、测试用例

// 测试1:给所有属性加2
var skills1 = new PlayerSkillsClass { Speed = 5, Agility = 3, Jump = 2, Strength = 4 };
skills1 = skills1 + 2;
// 结果:Speed=7, Agility=5, Jump=4, Strength=6

// 测试2:两个实例属性对应相加
var skills2 = new PlayerSkillsClass { Speed = 3, Agility = 2, Jump = 1, Strength = 5 };
var skills3 = skills1 + skills2;
// 结果:Speed=10, Agility=7, Jump=5, Strength=11

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:43:20