debugging 为什么我的C#类代码处于无限循环中?我该怎么做才能修复它?

sy5wg1nm  于 2023-01-13  发布在  C#
关注(0)|答案(3)|浏览(148)
namespace Random_walk_2d
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Point C = new Point(2, 5);

            C.Move('n');
            Point.Print(C);
        }
    }

    public class Point
    {
        public int x;
        public int y;

        readonly public Dictionary<char, Point> directions = new Dictionary<char, Point>()
        {
            { 'e', new Point(1, 0) },
            { 'n', new Point(0, 1) },
            { 'w', new Point(-1, 0) },
            { 's', new Point(0, -1) },
        };

        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public static Point operator +(Point A, Point B)
        {
            return new Point(A.x + B.x, A.y + B.y);
        }

        public static void Print(Point A)
        {
            Console.WriteLine($"({A.x}, {A.y})");
        }

        public void Move(char dir)
        {
            Point displacement = directions[dir];
            this.x += displacement.x;
            this.y += displacement.y;
        }

    }
}

我可以看出问题出在字典或Move()方法的某个地方,但我不明白的是,到底是什么原因导致了无限循环的发生?
我该如何解决这个问题呢?
我的朋友建议我在字典中使用2个整型数组而不是Point,但是......这有点违背了整个类的目的。如果我可以只使用2个整型数组,为什么要使用Point呢?我想要一个不这样做的解决方案。
如果你还有什么别的建议,一定要告诉我。
编辑:我应该马上提到这一点,但是当我运行它时,我在控制台中得到了无限多的at Random_walk_2d.Point..ctor(Int32, Int32)消息。
编辑2:我只是在试验类。在这个项目中,我想在一个2D网格上创建一个随机游走。一个2D网格可以很好地由一个带有2D点对象的类来建模。我需要Move()方法来向右(east = 'e'),向上(north = 'n')移动一个单位,等等。

cedebl8k

cedebl8k1#

问题是堆栈溢出,在这里完成

public class Point {
    public int x;
    public int y;

    readonly public Dictionary<char, Point> directions = new Dictionary<char, Point>()
    {
        { 'e', new Point(1, 0) },
        { 'n', new Point(0, 1) },
        { 'w', new Point(-1, 0) },
        { 's', new Point(0, -1) },
    };

当你创建一个点,它创建一个“方向”成员,这反过来创建4个新点,每个新点创建自己的“方向”每个创建4个点.....
不清楚你想做什么,但这修复了它

public class Point {
    public int x;
    public int y;

    static readonly public Dictionary<char, Point> directions = new Dictionary<char, Point>()
    {
        { 'e', new Point(1, 0) },
        { 'n', new Point(0, 1) },
        { 'w', new Point(-1, 0) },
        { 's', new Point(0, -1) },
    };

通过声明“directions”static,整个Point类只有一个,也许这就是您想要的
编辑-是的,这是你想要的“方向”Map实际上是一个常量,所以静态工作正常

1wnzp6jl

1wnzp6jl2#

你正在递归地、无限期地创建Point类型的新对象,因为在创建Point时,你正在创建一个有4个点的directions,每个点都有一个字典,字典中还有4个点,等等。

我不确定你到底想达到什么目的,因为从问题中还不清楚。所以我不能再帮你了。

b4lqfgs4

b4lqfgs43#

我建议使用静态变量来保存你的特定方向,而不是字典。我还建议,不要使用类,而是使用struct,以确保数据不会被我的意外改变。struct具有值语义,这意味着(x,y)对总是在一起。
这里有一个带有switch语句的函数,它可以返回正确的步骤,而不是字典。然后,我将使用一个技巧,覆盖Move()中的this关键字,以便一次性更改(x,y)的值。如果您已经定义了operator +,不妨使用它。

static class Program
{
    static void Main(string[] args)
    {
        Point C = new Point(2, 5);
        C.Move('n');
        Console.WriteLine(C);
    }
}

public struct Point
{
    public readonly int x;
    public readonly int y;

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public static readonly Point North = new Point(0, 1);
    public static readonly Point South = new Point(0, -1);
    public static readonly Point East = new Point(1, 0);
    public static readonly Point West = new Point(-1, 0);

    public Point GetDirection(char dir)
    {
        switch (dir)
        {
            case 'n': return North;
            case 'e': return East;
            case 's': return South;
            case 'w': return West;
            default:
                throw new ArgumentException("Invalid Direction.", nameof(dir));
        }
    }

    public static Point operator +(Point a, Point b) => new Point(a.x + b.x, a.y + b.y);

    public void Move(char dir)
    {
        Point delta = GetDirection(dir);
        this += delta;
    }
    public override string ToString()
    {
        return $"( {x}, {y} )";
    }
}

相关问题