Sorun

2010-11-20 31 views
2

Ben 2010 Visual Studio aşağıdaki sınıf oluşturmak ettik:Sorun

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); 
     } 
    } 

Ama sınıfının bir örneğini oluşturmaya çalıştığınızda, ben bana danışmanlık, bir yığın taşması istisna olsun sonsuz bir döngü veya sonsuz yineleme olmamasına dikkat edin. Ben instance'a olarak aşağıda iki farklı şekilde oluşturmak denedim:

Bat bottomBat; 
bottomBat = new Bat(); 

ve

Bat bottomBat = new Bat(); 

Ama program çalıştırmayı denediğinizde her iki yönde aynı hata döndürür. Ayrıca, sınıf tanımını public değiştiricisiyle birlikte ve denemeden de denedim.

Programlama konusunda oldukça yeniyim ve bu soruna ne neden olabileceği hakkında hiçbir fikrim yok. Yanlış bir şey mi yapıyorum?

Düzenleme:Bat sınıf için kod ı için gerekli düşünmemiştim ... her şey şu anda, bunun için özel bir yapıcı oluşturmadıysanız var mı?

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; 
     } 
    } 
+3

burada yeterli bilgi yoktur: Ancak, istisnai durumlarda, böyle bu sorunu çözebilir. Sınıfın tüm kurucularının yanı sıra temel sınıflarının kodlarını yayınlayabilir misiniz? (Bir BCL sınıfı olan bir temel sınıfa bastığınızda durabilirsiniz) – Ani

+0

Gönderdiğiniz kod ("playArea" referansına eksi çizgi), benim için gayet iyi çalışıyor, dolayısıyla sorun, yaptığınız bölümlerin birinde bulunmalıdır. t gönderi. –

+0

İstenildiği gibi, Form1 sınıfı için kod ekledim –

cevap

5

şekilde imkansız bir tür miras ve kompozisyon kombine anlaşılıyor. Taban Form1 türünde, türetilmiş Bat türünde olduğu bildirilen bir alan vardır. Ayrıca, bu tür bir yeni örneğine başlatmak için bir alan başlatıcısı kullanır. Açıkça, bir kaplumbağa-all-the-down-aşağı sorunu var: bir Bat (veya bu konu için bir Form1) oluşturduğunuzda, alan-başlatıcısı çalışacaktır - bu başka bir Bat örneğini oluşturacaktır, bu da sırayla olacak Henüz başka birBat oluşturun ve teoride ad-infinitum. (uygulamada: siz yığın-uzaydan bitene kadar). İşte

yığın taşması sorunu çözmek gerekir basit bir düzeltme, ama 'büyük resim' en uygun tasarım olmayabilir: Bu tip artık Form1 alt sınıfların nasıl

public class Bat 
{ 
    public void Draw(Graphics playArea) 
    { 
     ... 
    } 
} 

Bildirimi; doğrudan System.Object'dan miras alır. Artık ne Form1 ne de Bat sınıfları, bunların örnekleri oluşturulduğunda sonsuz yineleme göstermeyecektir.

Burada nihai amacı bilmeden en iyi düzeltmeyi önermek zor. Bu sınıfları tasarlamanın en iyi yolunu düşünmenizi öneririm. C# programlama dilini, OO tasarımını ve WinForms özelliklerini öğrenmeye zaman ayırmanız gerektiğini düşünürdüm. Ben düşünüyorum aslında burada OnPaint sanal yöntemi geçersiz kılmak için arıyorsunuz.

+0

Bu durumda, 'Form1' içindeki playArea 'nesnesine nasıl erişirim? Bunu zaten herkese açık olarak aldım, ancak ': Form1 '' Bat' sınıfından çıkardığımda, bu değişkene artık erişemiyorum. –

+1

@Saladin: 'playArea' nesnesine' Bat' sınıfındaki 'Form1' örneğiyle erişmelisiniz. Örneğin: "MyForm1.playArea" –

+0

@Saladin, Bat, Form1'i genişletirse, oluşturulan herhangi bir yarasa, oluşturduğu formdan değil, kendi * playArea öğelerini görür. –

0

Genellikle sebebi onun arka değişkeni ile bir özellik kafa karıştırıcı:

neyse, burada kendi bütünlüğü içinde Form1 sınıftır. çizgisinde

şey:

public class tmp 
{ 
    private int _x; 

    ... 

    public int X(x) 
    { 
     X = x; 
    } 
0

Basit bir sorununuz var.

sınıfınız Bat, Form1'den türetilmiştir ve Form1'de yeni bir Bat Örneği yaratırsınız, bu da Form1'e dayanır ve böylece yeni bir Bat .... örneğini oluşturur ve böylece yığın alanınıza kadar tekrarlanır. kadar kullanılır. Genelde

Form1 muhtemelen sınıf Bat hakkında bilmek olmamalı ve Bat hakkında bilmesi gereken tüm kod Bat sınıfta olması gerektiğini söyledi.

partial class Form1 
{ 
    public Form1(Bat _bat) 
    { 
    mBat = _Bat; 
    } 

    protected Bat mBat; 
} 

ve Bat sınıfına

public class Bat : Form1 
{ 
    public Bat() : base(this) 
    { 

    } 
}