Problem creating instance of a class
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 se开发者_如何学JAVAnder, EventArgs e)
{
timer1.Enabled = true;
}
}
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 derived Bat
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 a Bat
(or a Form1
for that matter), the field-initializer will run - this will create an instance of another Bat
, which in turn will create yet another Bat
, 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':
public class Bat
{
public void Draw(Graphics playArea)
{
...
}
}
Notice how this type no longer subclasses Form1
; it inherits directly from System.Object
. Now neither the Form1
nor the Bat
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:
public class tmp
{
private int _x;
...
public int X(x)
{
X = x;
}
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:
partial class Form1
{
public Form1(Bat _bat)
{
mBat = _Bat;
}
protected Bat mBat;
}
and on the Bat class
public class Bat : Form1
{
public Bat() : base(this)
{
}
}
精彩评论