C# Subfunktionen?

Atreju93

Lieutenant
Registriert
Nov. 2010
Beiträge
595
Hallo liebe CBler

Ich bin gerade dabei wider ein paar Dinge in C# zu programmieren.
Ich habe es mir selbst beigebracht und kenne daher viele Funktionen gar nicht erst
und google nach "Zufall" danach - wenn ich das Gefühl habe man könnte es auch anders lösen.

Folgendes ist auch jetzt der Fall: Ich habe ein Klickevent bei einem Buttonklick bzw. einfach die Klasse wenn ich auf einen Button klicke.

Folgender Code:

Code:
        // Funktion zum Navigieren - wurde hier in einem Click - Event verpackt. 
        private void button_go_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate(new Uri(textBox_url.Text));
            if (arraycount < 5)
            {
                if (arraycount == 0)
                {
                    url = textBox_url.Text;
                    arHistory[arraycount] = url;
                    MessageBox.Show(arHistory[arraycount], Convert.ToString(arraycount));
                    MessageBox.Show("Arraycounter ist Null");
                    arraycount++;
                }
                else
                {
                    url = textBox_url.Text;
                    arHistory[arraycount] = url;
                    MessageBox.Show(arHistory[arraycount], Convert.ToString(arraycount));
                    arraycount++;
                    MessageBox.Show("ArrayCount war nicht null sondern: " + Convert.ToString(arraycount));
                }
            }
            else
            {
                arraycount = 0;
                MessageBox.Show("History überfüllt - History wurde gelöscht");
                for (int i = 0; i < 5; i++)
                    arHistory[i] = null;
                MessageBox.Show("Aktueller Inhalt der Position 0 von ArHistory: " + arHistory[arraycount]);
                url = textBox_url.Text;
                arHistory[arraycount] = url;
                MessageBox.Show(arHistory[arraycount] + " " + Convert.ToString(arraycount));
            }
        }

Der Sinn hahinter ist ein Webbroser, bei dem ich eine Vor und Zurück - Funktion einbauen wollte. Daher legte ich ein Array an und bei jedem Klick auf den Go Button wird die aktuelle Adresse eine Position höher im Array abgelegt.

Wie ihr seht habe ich ich ein paarmal diese Codezeilen Drin:

Code:
                    url = textBox_url.Text;
                    arHistory[arraycount] = url;
                    MessageBox.Show(arHistory[arraycount], Convert.ToString(arraycount));

Es wäre elegant, wenn ich dies "Auslagern" könnte, da ich sie (und auch andere Codezeilen) anderorts auch noch brauche.

Ich kenne dass ich folgendes schreiben kann:

Code:
Private Void Navigieren()
{
                    url = textBox_url.Text;
                    arHistory[arraycount] = url;
                    MessageBox.Show(arHistory[arraycount], Convert.ToString(arraycount));
}

Und dann mit Navigieren(); zu dem Punkt springen kann.

mein Problem ist jedoch dass ich 1. dieses nicht im button_go_Click haben kann (gibt eine Fehlermeldung) und wenn ich es als eigene Klasse unterhalb definiere funktioniert dies zwar, aber sobald das Programm im Code weitergeht und zu "Private Void navigieren() {}" gelangt wird dieser Code auch ausgeführt (ist ja logisch..)

Gibt es eine möglichkeit eine Unterfunktion oder Unterklasse (keine Ahnung wie dies in C# heisst) zu konstruieren, dass ich innerhalb einer Private Void z.b. einen Bereich als Unterfunktion Navigieren () definieren kann und so auch (ev. sogar Global?) aufrufen kann?


Hoffe ihr Versteht was ich versuche zu Fragen :-)

Gruss
Atreju
 
Du musst nur die Übergabeparameter anpassen. Momentan hast du keine, auf was soll die Funktion zugreifen? Btw würde ich die Funktion als statisch markieren.
 
Folgendes ist auch jetzt der Fall: Ich habe ein Klickevent bei einem Buttonklick bzw. einfach die Klasse wenn ich auf einen Button klicke. ?

versteh ich ned ganze
wie meinst du einfach die klasse?
du rufst eine funktion auf mit dem klick auf den button
das event gibt der button mit um diverse eigentschaften des clicks bzw whatever.. abzufragen

wenn deine Navigieren() in der gleichen Class ist wie deine funktion für den mausklick ist diese durchaus bekannt...
wenn sie jedoch in einer anderen klasse ist must du zuerst diese klasse einbinden und um diese funktion direkt aufrufen zu können muss sie dazu noch public sein und nicht private

google einfach mal nach dem Thema Kapselung

@Yuuri aber nciht wenn url und das array global sind
 
Zuletzt bearbeitet:
Für was muss ich parameter übergeben?

Es sind ja keine Parameter erforderlich für diese paar Codezeilen.

Ich habe mir nur überlegt, dass es wohl effizienter wäre, wenn ich anstatt 5x die gleichen Codezeilen in jedem IF/Else schreibe diese Codezeilen "outsource" und dann diese aufrufe

ich stelle mir soetwas vor:

Code:
        private void button_go_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate(new Uri(textBox_url.Text));
            if (arraycount < 5)
            {
                if (arraycount == 0)
                {

                    MessageBox.Show(arHistory[arraycount], Convert.ToString(arraycount));
                    MessageBox.Show("Arraycounter ist Null");
                    MessageBox.Show(Convert.ToString(webBrowser1.Url));
                           Zeugserledigen();
                }

             Private Void ZeugsErledigen()
                    {
                                 url = textBox_url.Text;
                                 arHistory[arraycount] = url;
                                 arraycount++;
                                 arcntsub = true;
                    }
         }

Dies funktioniert natürlich nicht - aber so in etwa stelle ich mir dies vor...
 
Code:
private void button_go_Click(object sender, EventArgs e)
        {
		webBrowser1.Navigate(new Uri(textBox_url.Text));
		if (arraycount < 5)
		{
			if (arraycount == 0)
			{
				deinFunktionsname(arraycount,"Arraycounter ist Null")
				arraycount++;
			}
			else
			{
				deinFunktionsname(arraycount, "ArrayCount war nicht null sondern: " + Convert.ToString(arraycount))
				arraycount++;
			}
		}
		else
		{
			arraycount = 0;
			MessageBox.Show("History überfüllt - History wurde gelöscht");
			for (int i = 0; i < 5; i++)
				arHistory[i] = null;
		
			deinFunktionsname(arraycount, "Aktueller Inhalt der Position 0 von ArHistory: " + arHistory[arraycount])
	}
}

private void deinFunktionsname(int arraycount, string strError)
{
	url = textBox_url.Text;
        arHistory[arraycount] = url;
	MessageBox.Show(strError);
        MessageBox.Show(arHistory[arraycount] + " " + Convert.ToString(arraycount));
}

versuchs mal so
 
Man kann innerhalb einer Methode keine weitere definieren, d.h. die kannst du einfach in deiner Klasse definieren.

Kauf dir doch erst mal ein C#-Einsteigerbuch. Wie willst du ordentlich programmieren lernen, wenn du nicht mal die wichtigsten Grundlagen und Begriffe kennst?
 
@rille...
er sagte doch das so nicht funktioniert
er wollte hald nicht ncohmal die ganze funktion hinschreiben...
einfach mal klappe halten.... oder einfach produktiv beitragen...
Ergänzung ()

btw grad fällts mir auf
warum arbeitest du mit nem eigenen count für dein array?

arrayname.Length liefert die der länge des arrays
auserdem würd ich deine globalen variablen die du benutzt überdenken sollte alles lokal zu lösen sein
auser dein array wo jo
 
So ich habe es mittlerweile herausgefunden:

Einfach ein Public Void DoStuff() {CODE} und dann mit DoStuff(); aufrufen.
Das Ganze im public partial class FormMain : Form definieren dann klappt es.


@Xetoxyc

Wiso ich einen ArrCount benütze?

Ich speichere ja jede besuchte Webseite fortlaufend im Array ab. Und paralell dazu zähle ich einen Zähler hoch, der mir die Position der letzten Website im Array liefert. Wenn ich jetzt zurück klicke rechnet es den Zähler - 1 und dies ist dann die Position im Array der letzen Website. Wenn ich 2x auf Zurück klicke rechnet es den Zähler - 2 und so habe ich die Position der vorletzten Seite.
 
Einfach mal rumfummeln bis es irgendwie geht, sehe ich hier ständig bei unseren Studenten :rolleyes:
 
Nunja - wenn man nur Google und Foren zur Verfügung hat um C# zu lernen ist dies nicht wirklich einfach perfekt programmieren zu lernen..
 
Xetoxyc schrieb:
Code:
private void button_go_Click(object sender, EventArgs e)
        {
		webBrowser1.Navigate(new Uri(textBox_url.Text));
		if (arraycount < 5)
		{
			if (arraycount == 0)
			{
				deinFunktionsname(arraycount,"Arraycounter ist Null")
				arraycount++;
			}
			else
			{
				deinFunktionsname(arraycount, "ArrayCount war nicht null sondern: " + Convert.ToString(arraycount))
				arraycount++;
			}
		}
		else
		{
			arraycount = 0;
			MessageBox.Show("History überfüllt - History wurde gelöscht");
			for (int i = 0; i < 5; i++)
				arHistory[i] = null;
		
			deinFunktionsname(arraycount, "Aktueller Inhalt der Position 0 von ArHistory: " + arHistory[arraycount])
	}
}

private void deinFunktionsname(int arraycount, string strError)
{
	url = textBox_url.Text;
        arHistory[arraycount] = url;
	MessageBox.Show(strError);
        MessageBox.Show(arHistory[arraycount] + " " + Convert.ToString(arraycount));
}

versuchs mal so

Die Parameter kann er sich sparen, da die dazugehörigen Variablen Datenfelder der Klasse sind und damit auch sichtbar sind.

Xetoxyc schrieb:
@rille...
er sagte doch das so nicht funktioniert
er wollte hald nicht ncohmal die ganze funktion hinschreiben...
einfach mal klappe halten.... oder einfach produktiv beitragen...
Ergänzung ()

btw grad fällts mir auf
warum arbeitest du mit nem eigenen count für dein array?

arrayname.Length liefert die der länge des arrays
auserdem würd ich deine globalen variablen die du benutzt überdenken sollte alles lokal zu lösen sein
auser dein array wo jo

arrayname.Length liefert aber nur die Kapazität des Arrays, aber nicht die Anzahl der tatsächlich darin befindlichen Elemente. Deshalb ist das schon richtig so, wenn er keine List oder Stack verwendet.

rille schrieb:
Man kann innerhalb einer Methode keine weitere definieren, d.h. die kannst du einfach in deiner Klasse definieren.

Kauf dir doch erst mal ein C#-Einsteigerbuch. Wie willst du ordentlich programmieren lernen, wenn du nicht mal die wichtigsten Grundlagen und Begriffe kennst?

Da muss ich dir Recht geben, sonst bringt das relativ wenig.

Atreju93 schrieb:
Für was muss ich parameter übergeben?

Es sind ja keine Parameter erforderlich für diese paar Codezeilen.

Ich habe mir nur überlegt, dass es wohl effizienter wäre, wenn ich anstatt 5x die gleichen Codezeilen in jedem IF/Else schreibe diese Codezeilen "outsource" und dann diese aufrufe

ich stelle mir soetwas vor:

Code:
        private void button_go_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate(new Uri(textBox_url.Text));
            if (arraycount < 5)
            {
                if (arraycount == 0)
                {

                    MessageBox.Show(arHistory[arraycount], Convert.ToString(arraycount));
                    MessageBox.Show("Arraycounter ist Null");
                    MessageBox.Show(Convert.ToString(webBrowser1.Url));
                           Zeugserledigen();
                }

             Private Void ZeugsErledigen()
                    {
                                 url = textBox_url.Text;
                                 arHistory[arraycount] = url;
                                 arraycount++;
                                 arcntsub = true;
                    }
         }

Dies funktioniert natürlich nicht - aber so in etwa stelle ich mir dies vor...

Wie schon erwähnt, Methoden (und nein sie heißen nicht Funktionen) können nicht innerhalb einer anderen Methode deklariert werden. Eine Möglichkeit, warum der Compiler bei dir gemeckert haben könnte, wo du die Methode noch außerhalb der anderen deklariert hast, könnte die Großschreibung von "Private" und "Void" sein. Die MÜSSEN kleingeschrieben sein. Ich weiß aber nicht, ob du das tatsächlich gemacht hast.

mein Problem ist jedoch dass ich 1. dieses nicht im button_go_Click haben kann (gibt eine Fehlermeldung) und wenn ich es als eigene Klasse unterhalb definiere funktioniert dies zwar, aber sobald das Programm im Code weitergeht und zu "Private Void navigieren() {}" gelangt wird dieser Code auch ausgeführt (ist ja logisch..)

Die Methode wird erst ausgeführt, wenn du sie irgendwo aufrufst. Der Programmablauf führt nicht von oben nach unten innerhalb einer Klasse, sondern er beginnt in der Main-Methode und setzt sich in den Methoden fort, die du von dort aus aufrufst. Durch das Definieren einer Methode bedeutet dies nicht automatisch auch, dass sie aufgerufen wird. Dafür musst du zusätzlich noch sorgen.



edit: Wenn du dir kein Buch kaufen willst, kann ich dir die Seite hier empfehlen: http://openbook.galileocomputing.de/csharp/
 
Zuletzt bearbeitet:
Vielen Dank für die Antworten.

Ich habe bemerkt, dass es einen riesenmurks gibt dies mit einem Array zu lösen:

1. Das Array hat eine vordefinierte grösse - zwar kann man sagen dass wohl nie jemand mehr als 30 Sprünge zurück machen wird - jedoch möglich.

2. ein einfaches vor und Zurückspringen im Array ist nicht einfach. Mit meinen Zählern und Berechnungen gibt das einen instabilen Code mit viel Catch und IF/ELSE Anweisungen.

Ich werde mal sehen ob ich mit doppelt verketteten Listen etwas anfangen kann.
 
Atreju93 schrieb:
Ich werde mal sehen ob ich mit doppelt verketteten Listen etwas anfangen kann.
Die History ist doch im Prinzip nichts anderes als ein Stack von der reinen Überlegung her. Hab zwar nicht weiter drüber nachgedacht, aber vielleicht kannst du damit was anfangen.
 
Genau ein Stack kommt dem ziemlich nahe.

Mein Problem ist, dass ich bei einem C# Stack (nach meinem Wissen) nur Elemente darauf legen kann und einzeln wider davon nehmen kann. Ich kann somit nur in eine Richtung wandern - also z.b. nur Zurück.


EDIT:
Du hast mich aber auf eine Idee gebracht - was wäre, wenn ich zwei Stacks anlege - einen für Zurück und einen für Vorwärts? Das Heisst wenn ich zurückwandere in der History werden die gepushten Elemente vom Stack automatisch ins andere Stack gelegt und wenn ich dann wider vorwärts möchte werden einfach die Elemente aus dem Anderen Stack gelesen?
 
Genau darauf wollte ich hinaus. ;) Wäre für mich jetzt die einfachste und logischste Variante, bevor du dich weiter mit Listen und Arrays herumschlägst und dir dort Lösungen zurechtfrickelst.
 
@kinglouy
pob mehtode oder funktion


mindestens den text für die MsgBox muss er übergeben....
außerdem ist es nicht wirklich sinnvoll mit x-globals zu arbeiten....

arrayname.Length... liefert die kapazität... ein dümmerer kommentar is dier hierzu nicht eingefallen...



@TH
bleib doch bei ner list
eine reicht
damit kannste genau das machen was du willst
ohne mit stacks spielen zu müssen ;P
 
Also eine einfach verkettete liste oder eine Doppelt verkettete liste?

Kann dir gerade nicht folgen...
 
du hast ne list
an die hängst du neu besuchte seiten an

dann hast nen "endlos" verlauf
deine jetzt position merkst du dir natürlich wenn nun ein neuer klick auf vorwärst gemacht wird erhöst du deine position um 1 und nimmst diese url anderenfalls eben erniedrigen und pass auf deine bounds auf sonst crash dir das alles ;P

wenn du ne neue seite über nen links aufrufst musst du den verlauf der nach deiner jetztposition ist einfach löschen und die neuen urls adden

bei einen neuen klick auf zurück
 
Xetoxyc schrieb:
@kinglouy
pob mehtode oder funktion

Nein, nur Methode. Der Begriff "Funktion" existiert nicht in C#. Funktionen sind ein mathematischer Begriff und beschreibt im Grunde nur die Abbildung von einem Element aus einem Definitionsbereich auf ein Element des Wertebereichs. Da es aber auch Methoden mit leerer Parameterliste oder void als Rückgabetyp gibt, lässt sich hier an der Stelle nichts abbilden. Aus diesem Grund gab es in Prozeduralen Programmiersprachen die Unterscheidung zwischen Prozeduren (z.B. void als Rückgabetyp) und Funktionen (besitzt Parameter und Rückgabetyp != void). In modernen Sprachen sind alles einfach Methoden.

Xetoxyc schrieb:
außerdem ist es nicht wirklich sinnvoll mit x-globals zu arbeiten....

So viele "globals" wie nötig, nicht mehr. Die Dinger nennt man übrigens Datenfelder. Globals gibt es in dem Zusammenhang nicht. Datenfelder dürfen dann existieren, wenn sie in vielen Methoden gebraucht werden. Werden sie nur in einer oder wenigen benötigt, kann entweder eine weitere Abstraktion geschaffen werden, also eine neue Klasse, oder man regelt das als lokale Variable, sofern möglich. In seinem Fall könnte das Datenfeld "url" vermutlich lokal deklariert werden, allerdings das Array und arraycount nicht, solange er die Funktionalität der Liste/des Stacks weiterhin selbst implementiert, anstatt eine entsprechende Klasse des .Net Frameworks zu verwenden. Letzteres wäre in Hinblick auf die Kohäsion allerdings sinnvoller.


Xetoxyc schrieb:
arrayname.Length... liefert die kapazität... ein dümmerer kommentar is dier hierzu nicht eingefallen...

arrayname.Length liefert eben die Kapazität, also die Größe des Arrays. Nicht die Anzahl der tatsächlich geschriebenen/veränderten Elemente, da ein Array hier keine Unterscheidung trifft. Eine List und alle anderen Collection-Klassen geben die Anzahl der tatsächlich eingefügten Elemente mit der Property "Count" zurück. Von daher passt der Begriff.
 
Zuletzt bearbeitet:
ihr mit euren spitzfindigkeiten...
jeder weis was mit FUNKTION / METHODE gemeint ist... und jeder weis was drunter verstanden wird... nur weil deine funktionen die in c# mehtoden heisen und doch auf funktionen aufgebaut sind nicht funktionen sonder mehtoden heisen... ändert es nichts an der tatsache....

hab ich etwas falsch verstanden oder bezeichnest du ganz normale variablen als datenfelder ?
... meines wissens nach sind datenfelder arrays... und wenn du sie z.b. überhalb deiner main deklarierst sind die global bekannt... oder etwa nicht ?
 
Zurück
Oben