[C#] Auf bereits bestehende Klassenfunktion zugreifen

GreenKeeper

Neu angemeldet
Registriert
5 Aug. 2013
Beiträge
3
Hallo,
ich programmieren zur Zeit eine Anwendung, welche eine beliebige Anzahl von Lottoziehungen simulieren soll. Beim Klicken auf "button1" erstelle ich die Instanz "l" der Klasse Lotto und lasse die Funktionen durchlaufen, welche die Listen mit den nötigen Zahlen füllen.
Ich wollte jedoch noch einen Button (button2) hinzufügen mit dem ich die Listen auch wieder löschen kann, bzw. den Inhalt der Listen. Dabei stoße ich jedoch auf das Problem, das ich nicht auf die Funktion der Klasse Lotto zugreifen kann, da die Instanz ja in der Funktion von button1 liegt. Ich komme also nicht an die Daten aus der Klasse Lotto in der Instanz "l" heran. Ich hab schon recherchiert wie ich dieses Problem lösen kann aber bin nur auf die Verwendung von Events gestoßen. Dabei bin aber auch nicht weitergekommen und hab mich nun schlussendlich hier gemeldet. Ich hoffe ihr könnt mir bei dem Problem helfen. Ich bin auch bereit das Problem selbst zu lösen, wenn mir jemand einen Hinweis gibt wie dies zu machen ist aber aktuell weiß ich nicht weiter.

Den Code habe ich übersichtshalber gekürzt angehängt.

[src=csharp] class Lotto
{

List<int> urne = new List<int>(); //Lostrommel mit allen 49 Kugeln
List<int> einzelziehung = new List<int>(); //Gezogenen 6 Kugeln
List<int> gesamtziehung = new List<int>(); //Gezogene Zahlen aller Reihen

public Lotto(int kugeln, int gewkugeln, int ziehungen)
{
anzahlKugeln = kugeln;
gewinnkugeln = gewkugeln;
anzahlZiehungen = ziehungen;
}

void ClearUrne()
{
urne.Clear();
}

public void ClearAll()
{
einzelziehung.Clear();
gesamtziehung.Clear();
ergebnis.Clear();
}

public List<string> Go()
{
FillUrne(49);

for (int x = 0; x < anzahlZiehungen; x++)
{
Ziehung();
ClearUrne();
FillUrne(49);
}

return ergebnis;
}

}
}[/src]

[src=csharp] public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
try
{
int anzahlziehungen = Convert.ToInt32(textBox3.Text);
int kugeln = Convert.ToInt32(textBox1.Text);
int gewinnkugeln = Convert.ToInt32(textBox2.Text);

Lotto l = new Lotto(kugeln, gewinnkugeln, anzahlziehungen);
List<string> a = l.Go();
}

private void button2_Click(object sender, EventArgs e)
{
//TODO: Löschfunktion einbauen
}
}
}[/src]
 
Du kannst in der Klasse Form1 die Eigenschaft Lotto l definieren und in der button1_Click-Methode ordnest du nur noch l das neue Lotto-Objekt zu:
Code:
Expand Collapse Copy
    public partial class Form1 : Form
    {
        private Lotto l;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                int anzahlziehungen = Convert.ToInt32(textBox3.Text);
                int kugeln = Convert.ToInt32(textBox1.Text);
                int gewinnkugeln = Convert.ToInt32(textBox2.Text);

                l = new Lotto(kugeln, gewinnkugeln, anzahlziehungen);
                List<string> a = l.Go();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //TODO: Löschfunktion einbauen
            // l.clearAll(); oder so
        }
    }
}
 
Zwei Anmerkungen:

1) Man kann auch das Lotto-Objekt im Konstruktor vom Form aufrufen (public Form1()), das hat den Vorteil das es zu keiner Fehlermeldung kommt wenn man versehentlich auf Button 2 zuerst klickt. Ansonsten reißt man eine nette Nullpointerexception ;)

2) Gerade bei sowas wäre es dann schon eine Überlegung wert, ob man nicht einfach this verwendet. MMn. erhöht this einfach die Lesbarkeit, da man dann weiß von woher auf einmal die Variable kommt. Ist sicher für so n Miniprojekt irrelevant aber bei größeren Aufgaben ist es dann schon praktischer.
 
  • Thread Starter Thread Starter
  • #4
Danke für die Antworten. Die Idee von p3Eq hatte ich sogar auch zuerst aber ich dachte, dass es nicht gerade optimal ist das Objekt global zu erzeugen. Den Vorschlag von Larius hab ich auch umgesetzt, bin aber nicht sicher ob das richtig ist. Ich hab das Objekt nämlich nun im Konstruktor aufgerufen. Sorry falls ich sovie Frage und mich evtl. ein wenig blöd anstelle aber ich will mir nicht etwas aneignen was falsch seien könnte und frag darum sooft nach.;)
Code:
Expand Collapse Copy
 namespace LottoGenerator
{
    public partial class Form1 : Form
    {
        private Lotto _l;
        public Form1(Lotto l)
        {
            InitializeComponent();
            _l = l;
        }
 
private Lotto _l ist aber keine globale Variable. Sowas gibt es in C# nicht.

Mit Alternativen für die Vorgehensweise die p3Eq dir gezeigt hat sieht es eher schlecht aus. Da du in deiner Version Lotto l lokal deklariert hast wird das Objekt wieder vom Speicher gelöscht sobald die Methode durch ist. Wozu brauchst du dann eig. die Löschmethode?
 
Zuletzt bearbeitet:
Ich wollte jedoch noch einen Button (button2) hinzufügen mit dem ich die Listen auch wieder löschen kann, bzw. den Inhalt der Listen.
Warum eigentlich? Das Lottoobjekt wird doch eh verworfen und Du erzeugst beim nächsten mal ein neues.
 
Den Konstruktor musst du so belassen wie er war, sprich du machst folgenden Konstruktor:

Code:
Expand Collapse Copy
   public Form1()
        {
            InitializeComponent();
            _l = new Lotto();
        }

Ansonsten würde dein Programm nämlich erwarten das zum Start ein Lotto-Objekt an den Konstruktor übergeben wird, was aber nicht geschieht. Deshalb erzeugst du einfach beim Start selbst ein Objekt ;)
 
  • Thread Starter Thread Starter
  • #8
@Larius Ach so, jetzt hab ichs verstanden. Danke.
@KaPiTN Oh, das das Objekt eh verworfen wird (durch den garbage collector, richtig?) war mir nicht bewusst.

Ich seh schon ich muss noch viel lernen, damit ich solche Fehler nicht mehr mache. Trotzdem Danke für die Hilfe und die Erklärungen
 
Ja, das Objekt wird durch den Garbage Collector gekübelt, aber: Das sollte man sich nicht angewöhnen das man ständig ein neues Objekt erzeugt. Nur, weil die Referenz auf das Objekt nicht mehr vorhanden ist, heisst es noch lange nicht, das sofort der GC anspringt und es entfernt
 
Da hat Larius recht. Die Referenz des Objektes (z.B. Lotto l) kannst du löschen wenn du l auf null setzt (l = null). Wenn es nötig wird kannst du auch manuell den Garbage Collector anwerfen (GC.Collect();). Dies kann man z.B. machen wenn man gerade eine große Methode mit vielen Objekten abgearbeitet hat.
 
Zurück
Oben