如何在Get / Set中修复StackOverflow异常?

时间:2015-04-11 15:28:49

标签: c# stack-overflow

请记住,这是我学习C#的第一天;这也是我的第一个编译语言,所以我绝对不习惯'类型'的概念。我来自Python。

似乎强类型语言比Python更难一个数量级... v_v'

我收到了StackOverflow异常,但我不知道原因:

    static void Main(string[] args)
    {
        Dictionary<string, int> init = new Dictionary<string,int>();
        init["stepId"] = 250;
        init["offset"] = 13;
        init["inc"] = 113;
        init["danger"] = 0;
        StepGenerator gen = new StepGenerator(init);
        Console.Write("Next: {0}", gen.Step["stepId"]);
        Console.Read();

错误似乎在这里:

    public Dictionary<string, int> Step
    {
        get { return Step; }
        set
        {
            Dictionary<string, int> step = value;
            // It complains about this line, and suggests an infinite recursion.
            step["rnd"] = genRnd(rnlut[step["stepId"]], step["offset"]);
            step["limit"] = genDangerLimit(step["rnd"]);
            step["enc"] = genEnc(step["danger"], step["limit"]);
            Step = step;
        }

完整:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace rePlanner
    {
        public class StepGenerator
        {
            // snipped array size:
            private static readonly int[] rnlut = new int[] {0xB1}
        enum Input
        {
            B,
            G,
        };

        enum Encounter
        {
            No,
            Yes,
        }

        enum Type
        {
            Run,
            Walk,
            Stutter,
            Unit,
        }
        public Dictionary<string, int> Step
        {
            get { return Step; }
            set
            {
                Dictionary<string, int> step = value;
                step["rnd"] = genRnd(rnlut[step["stepId"]], step["offset"]);
                step["limit"] = genDangerLimit(step["rnd"]);
                step["enc"] = genEnc(step["danger"], step["limit"]);
                Step = step;
            }
        }
        internal int stepId {get; set;}
        internal int offset { get; set;}
        internal int danger { get; set; }
        internal int rnd { get; set; }
        internal int dangerLimit { get; set; }
        internal int enc { get; set; }
        internal int type { get; set; }
        internal int units { get; set; }
        public int input { get; set; }


        // Constructor.
       public StepGenerator(Dictionary<string, int> step)
        {
            this.Step = step;
        }

        private int genStepId(int oldStepId)
        {
            return (oldStepId + 2) & 0xFF;
        }

        private int genOffset(int oldOffset, int stepId)
        {
            if (stepId == 0)
            {
                int offset = (oldOffset + 13) & 0xFF;
            }
            else
            {
                offset = oldOffset;
            }
            return offset;
        }

        private int genDanger(int oldDanger, int oldInc)
        {
            danger = oldDanger;
            danger += oldInc;
            if (danger > 65535)
            {
                danger = oldInc;
            }
            return danger;
        }

        private int genRnd(int rnlut, int offset)
        {
            return (rnlut - offset) & 0xFF;
        }

        private int genDangerLimit(int rnd)
        {
            return ((rnd + 1) * 256);
        }

        private int genEnc(int danger, int dangerLimit)
        {
            if(danger > dangerLimit)
            {
                return (int)Encounter.Yes;
            }
            return  (int)Encounter.No;
        }

        public Dictionary<string, int> next()
        {
            Dictionary<string, int> step = this.Step;
            step["stepId"] = genStepId(this.Step["stepId"]);
            step["offset"] = genOffset(this.Step["offset"], this.Step["stepId"]);
            step["danger"] = genDanger(this.Step["danger"], this.Step["inc"]);
            step["rnd"] = genRnd(rnlut[step["stepId"]], step["offset"]);
            step["limit"] = genDangerLimit(step["rnd"]);
            step["enc"] = genEnc(step["danger"], step["limit"]);
            this.Step = step;
            return step;
        }

    }
}

1 个答案:

答案 0 :(得分:1)

您使用行

重复调用Step上的setter
Step = step;

这会导致无限递归。

我认为您需要将Step属性设置为私有step成员变量的getter和setter。首先,删除

Dictionary<string, int> step = value;
来自Step setter的

。将step设为StepGenerator的私有成员变量:

private Dictionary<string, int> step;

将您的Step属性更改为:

public Dictionary<string, int> Step
{
    get { return this.step; }

    set
    {
        this.step = value;
        this.step["rnd"] = genRnd(rnlut[step["stepId"]], step["offset"]);
        this.step["limit"] = genDangerLimit(step["rnd"]);
        this.step["enc"] = genEnc(step["danger"], step["limit"]);
    }
}