C#First Simple Class

时间:2018-06-02 19:52:24

标签: c# class console

所以我开始学习C#(实际上这是我的第3天),我正在向左和向右戳。

所以我使用的是Console,我创建了我的第一个非常简单的类

using System.Timers;

public class Star
{
    private int x, y;

    public Star(int fx, int fy)
    {
        Create(fx, fy);
        Move();
    }

    private void Create(int fx, int fy)
    {
        this.x = fx;
        this.y = fy;
        Console.SetCursorPosition(this.x, this.y);
        Console.Write("*");
    }
    private void Move()
    {
        Timer aTimer = new Timer();
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = 500;
        aTimer.AutoReset = false;
        aTimer.Start();

    }
    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Console.SetCursorPosition(this.x, this.y);
        Console.Write(" ");
    }
}

}

我有一个主程序循环,它不停地等待用户输入,它有不同的状态。

while (true)
{
    if (Mode == 0)
    {
        Console.SetCursorPosition(tX, tY);
        Console.BackgroundColor = ConsoleColor.Black;
        Console.Write("[ " + System.DateTime.Now + " ]");

        Cursor(Selection, OldSelection);
    }
    if (Mode == 2)
    {
        Random r = new Random();

        System.Threading.Thread.Sleep(500);

        for (int i = 0; i< 10; i++)
            Star myStar = new Star(r.Next(nScreenWidth), r.Next(nScreenHeight));
    }


    if (Console.KeyAvailable)
    {
        ConsoleKeyInfo keyInfo = Console.ReadKey(true);

        if (Mode == 0)
        {
            switch (keyInfo.Key)
            {
                case ConsoleKey.DownArrow:
                    OldSelection = Selection;

                    if (Selection == 4) Selection = 0;
                    else Selection++;
                break;
                case ConsoleKey.UpArrow:
                    OldSelection = Selection;

                    if (Selection == 0) Selection = 4;
                    else Selection--;
                break;
                case ConsoleKey.Enter:
                    if (Selection == 0)
                    {
                        Console.Clear();
                        Mode = 1;
                    }

                    if (Selection == 1)
                    {
                        Console.Clear();
                        Mode = 2;
                    }

                    if (Selection == 4) return;
                break;
            }
        }

        if (keyInfo.Key == ConsoleKey.Escape)
        {
            Console.Clear();
            MainMenu();
            Mode = 0;
        }
    }
}

我的问题是,当我启动星星(模式2)时,它会在随机位置显示星星,但是如果我退出此状态,物体不会立即死亡,它们的计时器仍然在执行,并且它们正在定位光标 - 位置,并拧紧主菜单。我可能这里有点可怕,但我不知道是什么。

此致 罗伯特

最终工作示例

在IRC上查了一下之后,我被告知最好使用一个Timer,因为我已经有了一个主循环。我改变了我的代码。

首先是班级

   public class Star : IDisposable
    {
        public static int instances = 0;

        public Star(int fx, int fy)
        {
            Create(fx, fy);
            Animate();
        }

        int x, y, animpos;

        private void Create(int fx, int fy)
        {
            this.x = fx;
            this.y = fy;
            this.animpos = 0;

            instances++;
        }

        public void Animate()
        {
            Console.SetCursorPosition(this.x, this.y);

            switch (animpos)
            {
                case 0:
                    {
                        Console.Write("+");
                    }
                    break;
                case 1:
                    {
                        Console.Write("*");
                    }
                    break;
                case 2:
                    {
                        Console.Write(".");
                    }
                    break;
            }
            animpos++;
            if (animpos == 3) { animpos = 0; }
        }

        public void Dispose()
        {
            instances--;
        }
    }

然后是程序中的主循环,只有相关部分:

        if (Mode == 2)
        {
            System.Threading.Thread.Sleep(200);

            if(Star.instances < 30)
            {
                Star myStar = new Star(r.Next(nScreenWidth-1), r.Next(nScreenHeight-1));
                stars.Add(myStar);
            }

            if (stars.Count != 0)
            {
                foreach(var star in stars)
                {
                    star.Animate();
                }
            }

            Console.SetCursorPosition(0, nScreenHeight-1);
            Console.Write("NUMBER OF STARS ON SCREEN : " + Star.instances);
        }

我把Dispose留在那里,只是为了记住这一点,将来我希望能生成更复杂的代码。但我想这并不是真的需要它。

再次感谢你!

1 个答案:

答案 0 :(得分:1)

您尝试每500毫秒创建10个Star类的实例,但您没有维护对这些对象的引用。

您需要将它们添加到集合中,例如列表...

static List<Star> stars = new List<Star>();

for (int i = 0; i< 10; i++)
{
    Star myStar = new Star(r.Next(nScreenWidth), r.Next(nScreenHeight));
    stars.Add(myStar);
}

然后,当您退出主菜单时,您需要明确处理这些实例,以确保他们的计时器不再触发。

在C#中,通常的做法是在您希望能够明确处理的类中实现IDisposable接口...

public class Star : IDisposable
{
    ...
    public void Dispose()
    {
        if (aTimer != null)
        {
            aTimer.Dispose();
            aTimer = null;
        }
    }
    ...
}

然后,您可以通过调用处理它们来处置您的Star实例...

if (keyInfo.Key == ConsoleKey.Escape)
{
    foreach (var star in stars)
        star.Dispose();
    Console.Clear();
    MainMenu();
    Mode = 0;
}