创建类的实例时出现问题
我在 Visual Studio 2010 中创建了以下类:
public class Bat : Form1
{
public int BatLocation;
public void draw()
{
Pen batPen = new Pen(Color.Black);
batPen.Width = 10;
playArea.DrawRectangle(batPen, BatLocation, (picPlayArea.Height - 30), 50, 10);
}
}
但是当我尝试创建该类的实例时,出现堆栈溢出异常,建议我确保没有无限循环或无限递归。我尝试了两种不同的方式创建实例,如下所示:
Bat bottomBat;
bottomBat = new Bat();
并且
Bat bottomBat = new Bat();
但是当我尝试运行程序时,两种方式都会返回相同的错误。我还尝试了使用和不使用 public
修饰符的类定义。
我对编程很陌生,不知道是什么导致了这个问题。我做错了什么吗?
编辑: Bat
类的代码是我目前所拥有的一切,还没有为其创建特定的构造函数...您认为我不需要吗?
无论如何,这是完整的 Form1 类:
public partial class Form1 : Form
{
// Define various objects for the game
public Graphics playArea;
Bat bottomBat = new Bat();
public Form1()
{
InitializeComponent();
// Create instances of objects
playArea = picPlayArea.CreateGraphics();
//bottomBat = new Bat();
// Delegate the mouseMove event for picPlayArea
picPlayArea.MouseMove += new MouseEventHandler(picPlayArea_MouseMove);
}
private void picPlayArea_MouseMove(object sender, MouseEventArgs e)
{
bottomBat.Location = e.X;
}
private void btnExit_Click(object sender, EventArgs e)
{
string msg = "Are you sure you want to exit?",
title = "Confirm Exit";
DialogResult res = MessageBox.Show(msg, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (res == DialogResult.Yes)
{
Environment.Exit(0);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
// This is where most of the functionality is executed within the game
playArea.Clear(Color.White);
}
private void btnStart_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
}
I've create the following class in Visual Studio 2010:
public class Bat : Form1
{
public int BatLocation;
public void draw()
{
Pen batPen = new Pen(Color.Black);
batPen.Width = 10;
playArea.DrawRectangle(batPen, BatLocation, (picPlayArea.Height - 30), 50, 10);
}
}
But when I try to create an instance of the class, I get a stack overflow exception, advising me to make sure that I don't have an infinite loop or infinite recursion. I have tried creating the instance two different ways, as below:
Bat bottomBat;
bottomBat = new Bat();
and
Bat bottomBat = new Bat();
But both ways return the same error when I try to run the program. I've also tried the class definition with and without the public
modifier.
I'm pretty new to programming and have no idea what might be causing this problem. Am I doing something wrong?
Edit: The code for the Bat
class is everything I have at the moment, haven't created a specific constructor for it... Didn't think I needed to?
Anyway, here is the Form1 class in its entirety:
public partial class Form1 : Form
{
// Define various objects for the game
public Graphics playArea;
Bat bottomBat = new Bat();
public Form1()
{
InitializeComponent();
// Create instances of objects
playArea = picPlayArea.CreateGraphics();
//bottomBat = new Bat();
// Delegate the mouseMove event for picPlayArea
picPlayArea.MouseMove += new MouseEventHandler(picPlayArea_MouseMove);
}
private void picPlayArea_MouseMove(object sender, MouseEventArgs e)
{
bottomBat.Location = e.X;
}
private void btnExit_Click(object sender, EventArgs e)
{
string msg = "Are you sure you want to exit?",
title = "Confirm Exit";
DialogResult res = MessageBox.Show(msg, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (res == DialogResult.Yes)
{
Environment.Exit(0);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
// This is where most of the functionality is executed within the game
playArea.Clear(Color.White);
}
private void btnStart_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看来您以一种不可能的方式将继承和组合结合起来。基本
Form1
类型有一个声明为派生Bat
类型的字段。此外,它还使用字段初始化程序将其初始化为该类型的新实例。显然,您遇到了一个乌龟一直向下的问题:当您创建一个Bat
(或一个Form1
)时,字段初始化程序将运行- 这将创建另一个Bat
的实例,而该实例又会创建另一个Bat
,依此类推,理论上是无限的。 (实际上:直到用完堆栈空间)。这是一个简单的修复,应该可以解决堆栈溢出问题,但可能不是“全局”中最合适的设计:
请注意此类型如何不再是
Form1
的子类;它直接继承自System.Object
。现在,在创建Form1
和Bat
类的实例时,它们都不会表现出无限递归。如果不知道这里的最终目标,就很难提出最佳修复方案。我建议您考虑一下设计这些类的最佳方法。我认为您需要花一些时间学习 C# 编程语言、OO 设计以及 WinForms 细节。我认为您实际上希望覆盖
OnPaint
虚拟方法。It appears you have combined inheritance and composition in an impossible sort of way. The base
Form1
type has a field declared to be of the derivedBat
type. In addition, it uses a field-initializer to initialize it to a new instance of that type. Clearly, you have a turtles-all-the-way-down issue: when you create aBat
(or aForm1
for that matter), the field-initializer will run - this will create an instance of anotherBat
, which in turn will create yet anotherBat
, and so on, ad-infinitum in theory. (in practice: until you run out of stack-space).Here's a simple fix that should solve the stack-overflow issue, but may not be the most appropriate design in the 'big-picture':
Notice how this type no longer subclasses
Form1
; it inherits directly fromSystem.Object
. Now neither theForm1
nor theBat
classes will exhibit infinite recursion when instances of them are created.It's hard to suggest the best fix without knowing the ultimate aim here. I suggest you give some thought to the best way to design these classes. I would think you need to spend some time learning about the C# programming language, OO design, as well as WinForms specifics. I think you're actually looking to override the
OnPaint
virtual method here.通常原因是将属性与其支持变量混淆。
大致如下:
Often the cause is confusing a property with its backing variable.
Something along the lines of:
你有一个简单的问题。
你的类 Bat 是从 Form1 派生的,在 Form1 中你创建了一个新的 Bat 实例,而该实例又基于 Form1,因此创建了一个新的 Bat 实例......如此重复,直到你的堆栈空间用完。
一般来说,Form1 可能不应该了解 Bat 类,并且所有需要了解 Bat 的代码都应该位于 Bat 类中。但是,在特殊情况下,您可以像这样解决这个问题:
并且在 Bat 类上
You have a simple problem.
your class Bat is derived from Form1, and in Form1 you create a new instance of Bat, which in turn is based on Form1 so that creates a new instance of Bat.... and so it repeats until your stack space is used up.
In general, Form1 probably should not know about the class Bat, and that all code that needs to know about Bat should be in the Bat class. However, in exceptional circumstances, you can solve this issue like this:
and on the Bat class