C# [F] Array Grundlagen mit Code+Pic

@SoDaTierchen

Ich möchte meine Visual C# Skills verbessern und habe mich gerade sehr gefreut, dass du deinen Code eine übungsaufgabe für das logische verstehen vom sehen ist.

Du hast recht, ich bin ein Anfänger. Denn wenn wir die Gesamtheit von C# nehmen wissen, dass C# Riesengroß ist.

edit: oh doch nicht überarbeitet.
 
Zuletzt bearbeitet:
SoDaTierchen schrieb:
Sollte es aber tatsächlich NUR um die Ausgabe und gar nicht um den Lerneffekt gegangen sein, so ist dein Beitrag natürlich der wertvollste.

So kann man sich natürlich auch rausreden, wenn man schlechten Code produziert. Argumentierst du bei deinem Chef auch so wenn dein Code nicht das macht was er soll?

edit:
Außerdem ist mein Code besser, weil ich nur EINMAL in das Textfeld schreibe! Bei deinem Code wird 6 mal das TextChanged-Ereignis ausgelöst, bei meinem nur einmal. Auch ein beliebter Anfängerfehler...
 
Zuletzt bearbeitet:
SheldonCooper schrieb:
So kann man sich natürlich auch rausreden, wenn man schlechten Code produziert. Argumentierst du bei deinem Chef auch so wenn dein Code nicht das macht was er soll?

edit:
Außerdem ist mein Code besser, weil ich nur EINMAL in das Textfeld schreibe! Bei deinem Code wird 6 mal das TextChanged-Ereignis ausgelöst, bei meinem nur einmal. Auch ein beliebter Anfängerfehler...

6x hintereinander spielt keine Rolle. Solche sinnlos Optimierungen kann man sich sparen. Und außerdem wäre es dem Anfänger ohne Hinweis sowieso nicht aufgefallen somit: epic fail :schaf:

Dem nächsten Programmieranfänger könnt ihr helfen und euch für Kings halten. Bewerft euch ruhig weiter mit s.....
 
Zuletzt bearbeitet von einem Moderator:
Zusammenfassung: Mein code fängt schonmal falsch an und hat mich die ganze zeit total irritiert, weil ich immer den Anfang meines falschen codes mitkopiert habe. Sorry.

SoDaTierchen sein Code:

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            int[] myarray = new int[5];
            myarray[0] = 1;
            myarray[1] = 2;
            myarray[2] = 3;
            myarray[3] = 4;
            myarray[4] = 5;

            richTextBox1.Text = "";
            for (int i = 0; i < myarray.Length; i++)
            {
                richTextBox1.Text += Convert.ToString(myarray[i]) + "\n";
            }
            





        }





    }
}
 
can320 schrieb:
6x hintereinander spielt keine Rolle.
In dem Beispiel nicht, unter Umständen kann dieser Stil aber fatale Folgen haben.
can320 schrieb:
Solche sinnlos Optimierungen kann man sich sparen.
Was DU nicht verstehst ist also sinnlos?
can320 schrieb:
Und außerdem wäre es dem Anfänger ohne Hinweis sowieso nicht aufgefallen somit: epic fail :schaf:
Gerade weil ihm das nicht auffällt sollte man ihm solchen Mist nicht beibringen.
Ergänzung ()

lxlox schrieb:
SoDaTierchen sein Code:
Da ist noch immer das Problem drin, dass er 6 mal in die Textbox schreibt... Hast du irgendein Problem mit mir und meinem Code?! Wegen Leuten wie dir hab ich langsam keine Lust mehr DAUs zu helfen...
 
lxlox schrieb:
Dein Code ist auch toll. :)
Wieso auch??? Das impliziert, dass mindestens einer der anderen auch toll wäre. Das dies nicht so ist hab ich doch schon erklärt, oder? Hier ein Tipp für dich als Anfänger: trenne immer UI und Daten. Die Richtextbox ist eindeutig UI, das Array und der String eindeutig Daten. Baue niemals deinen String in der Textbox zusammen, das macht man einfach nicht. Zuerst erzeugst du deinen String, dann weist du ihn der Textbox zu. Alles andere ist schlechter Stil. Stell dir mal vor, du machst in der Schleife noch mehr, wo evtl. auch was schief gehen kann (try catch). Du hast dann u.U. undefinierten Mist in deiner Textbox und dein Programm stürzt ab. Das gilt nicht nur für Textboxen, sondern eigentlich immer. Achte besser darauf, wo du deine Fragen stellst und von wem du Antworten akzeptierst, nicht jeder in diesem Forum kann richtig programmieren, wie du siehst.
 
@SheldonCooper
Wenn ich richtig programmieren könnte, dann hätte ich dem Fragesteller erklärt, dass es besser wäre den String mittels StringBuilder zu erzeugen, statt mit jedem Schleifendurchlauf eine neue String Instanz zu generieren! Aber das auch nur, wenn ich richtig programmieren könnte.

Das Wetter ist zu schön, ich lass mir jetzt mal lieber die Sonne auf den Bauch scheinen...
 
Touché! Sehr guter Kommentar. Ich stimme dir zu 100% zu.

edit: Da ich ja offensichtlich auch nicht programmieren kann, bitte nenne mir mal die Vorteile des StringBuilders in diesem Beispiel. Meine Variante ist ja schneller als die Variante mit dem StringBuilder (noch schneller wäre übrigens String.Concat). Das mit dem StringBuilder hab ich noch nicht oft gemacht, nur wenn ich mit Dateien gearbeitet habe. Ich hab schon öfters gehört, dass StringBuilder besser sein soll. Hast du eine konkrete Quelle, die erklärt, warum StringBuilder in diesem Beispiel Vorteile hat?
 
Zuletzt bearbeitet:
Klar, dann ist es wichtig. In diesem konkreten Fall jedoch eher kontraproduktiv, oder? Hat der StringBuilder bei 5 Iterationen neben den bekannten Nachteilen auch Vorteile? Würdest du in diesem Fall mit StringBuilder arbeiten? Wenn ja: warum?
 
can320 schrieb:
6x hintereinander spielt keine Rolle. Solche sinnlos Optimierungen kann man sich sparen. Und außerdem wäre es dem Anfänger ohne Hinweis sowieso nicht aufgefallen somit: epic fail :schaf:

Dem nächsten Programmieranfänger könnt ihr helfen und euch für Kings halten. Bewerft euch ruhig weiter mit s.....

Full Ack.
Ich frage mich, wieso noch niemand den TE auf WeakReferences aufmerksam gemacht hat. In Verbindung mit Events ist das auch ein beliebter "Anfänger-Fehler". Noch besser ein Arch.Pattern, MVC vlt. oder MVVM - bestimmt spannend bei Forms.

SheldonCooper schrieb:
Klar, dann ist es wichtig. In diesem konkreten Fall jedoch eher kontraproduktiv, oder? Hat der StringBuilder bei 5 Iterationen neben den bekannten Nachteilen auch Vorteile? Würdest du in diesem Fall mit StringBuilder arbeiten? Wenn ja: warum?

Kontraproduktiv ist hier das falsche Wort.
string.Concat alloziert einfach nur einen entsprechend großen Char-Array und befüllt diesen mit den übergebenen Werten.
Der StringBuilder hingegen nutzt intern eine Liste, die bei Bedarf vergrößert werden kann, bevor die gleiche Magie wie bei string.Concat zu tragen kommt.

Die Anwendungsfälle sollten klar sein. Der StringBuilder kommt immer dann zum Einsatz, wenn die Anzahl an Iterationen unbekannt ist.

Vom Stil mal abgesehen ist es aber auch wurscht, wie man das ganze zusammen baut - solange man sich nicht für string.Insert entscheidet. Wir sprechen hier von wenigen Millisekunden unterschied bei 1Mio. Iterationen. Wer meint das "optimieren" zu müssen, ist bei .NET sowieso falsch.
Nebenbei wundert es mich , dass du i++ und nicht ++i schreibst ;)

Und nun klink ich mich wieder aus. In dieser Diskussion gibt es, für meinen Geschmack, zu viele sinnlose Kommentare - meinen inklusive.
 
Um das noch zu klären :). Man kann sagen, dass bei i++ ein temporäres Objekt benötigt wird. Allerdings geht das eher auf C-Zeiten zurück. Moderne Compiler optimieren den Unterschied weg, wenn i++ als einzelnes Statement steht wie in der for-Schleife.

Aber mal ehrlich der Thread ist im Moment weit weg von seinem Ausgangspunkt. Natürlich sollte man versuchen einem Anfänger nicht erst "falsche" Dinge beizubringen. Aber hey nenne mir eine Person die von Anfang an perfekt Programmieren gelernt hat.

Und @SheldonCooper: Ist dir Lob so wichtig, dass du gleich so abgehen musst? Eine Erklärung wieso deine Lösung besser/korrekter ist hätte dem TE mehr geholfen. Also bleiben wir lieber alle friedlich und helfen auch denen, die mit Optimierung noch nichts anfangen wollen. :)
 
SheldonCooper schrieb:
Wieso auch??? Das impliziert, dass mindestens einer der anderen auch toll wäre. Das dies nicht so ist hab ich doch schon erklärt, oder? Hier ein Tipp für dich als Anfänger: trenne immer UI und Daten. Die Richtextbox ist eindeutig UI, das Array und der String eindeutig Daten. Baue niemals deinen String in der Textbox zusammen, das macht man einfach nicht. Zuerst erzeugst du deinen String, dann weist du ihn der Textbox zu. Alles andere ist schlechter Stil. Stell dir mal vor, du machst in der Schleife noch mehr, wo evtl. auch was schief gehen kann (try catch). Du hast dann u.U. undefinierten Mist in deiner Textbox und dein Programm stürzt ab. Das gilt nicht nur für Textboxen, sondern eigentlich immer. Achte besser darauf, wo du deine Fragen stellst und von wem du Antworten akzeptierst, nicht jeder in diesem Forum kann richtig programmieren, wie du siehst.

Ich setze mich weiterhin mit Arrays momentan auseinander. Deine Aussage: "trenne immer UI und Daten" hat mich zum nachdenken angeregt. Ich habe es umgesetzt. Irgendwann bin ich jedoch auf etwas gestoßen, wo soetwas nicht klappt. Jedoch die kombination aus UI und Daten schon.

Dazu habe ich 2 fehlerhafte Beispiele erstellt, die bei dem Array etwas anders aussehen. Siehe Bilder und Code.


Beispiel 1:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            string[] hallo = {"1", "2", "3", "4"};
            string amx = "";
            
            richTextBox1.Text = "";
            
           
            for (int i=0; i<hallo.Length; i++)
            {
                   hallo[i] += i;
                   i++;
                   amx+=hallo[i]+"\n";
                   richTextBox1.Text = amx;
               }
               
            
        }

Beispiel 2:

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {          
             string[] hallo = {"1", "2", "3", "4"};
            int i=0;
            string amx = "";
            richTextBox1.Text = "";
            while (true)
            {
                try
                {
                    hallo[i] += i + 0;
                    i++;
                    amx += hallo[i] + "\n";
                    richTextBox1.Text = amx;
                }
                catch
                { break; }
            }            
        }
    }
}

for array frage1.jpg
try frage.jpg

Wie kann ich das Problem beheben, ohne eine Kombination aus UI und Daten?
 
lxlox schrieb:
Deine Aussage: "trenne immer UI und Daten" hat mich zum nachdenken angeregt.

Ich bitte dich inständig dieses "Zitat" weitestgehend aus deinem Gedächtnis zu streichen ;)
Trennung von UI und Daten meint etwas komplett anderes. Mit deinem Problem hat das rein gar nichts zu tun. Nichtsdestotrotz hat Sheldon halbwegs recht, wenn er dir dazu rät alle Operationen auf einer separaten Variable zu erledigen und diese dann deiner Control zuzuweisen. (Auch wenn seine Begründung nicht ganz korrekt ist)

Kurz zur Erklärung. Weiter oben wurde schon das Thema mit dem TextChangedEvent angerissen. Das ist ein Ereignis, dass ausgelöst wird, wenn sich der Inhalt der RTB ändert. Das ganze passiert innerhalb der Klasse RichTextBox. Auf was ich hinaus will: wenn du innerhalb einer Schleife immer wieder einen Setter einer Klasse aufrufst, musst du davon ausgehen, dass innerhalb dieser Klasse irgendwas mit den neu gesetzten Daten passiert.
Manchmal ist das egal, manchmal will man das auf jeden Fall vermeiden und es gibt Szenarien, in denen es gewünscht ist.

Zu deinem jetzigen Problem.
Es scheint so als müsstest du dich auch nochmal ein wenig mit Schleifen beschäftigen ;)
lxlox schrieb:
Code:
        private void button1_Click(object sender, EventArgs e)
        {

            string[] hallo = {"1", "2", "3", "4"};
            string amx = "";
            
            richTextBox1.Text = "";
            
            for (int i=0; i<hallo.Length; i++)
            {
                   hallo[i] += i;
                   i++;
                   amx+=hallo[i]+"\n";
                   richTextBox1.Text = amx;
               }
        }

Hier sind gleiche mehrere Zeilen mehr oder weniger falsch.

Code:
richTextBox1.Text = "";
Kannst du dir sparen, wenn du sowieso vor hast den Text zu überschreiben.

Code:
richTextBox1.Text = amx;
Hier das gleiche "Problem" wie in einem deiner vorherigen Posts. Du setzt das Text Property innerhalb der Schleife. Da passiert nichts weiter schlimmes, ausser das du unnötige Strings erzeugst.

Code:
hallo[i] += i;
i++;
amx+=hallo[i]+"\n";
Und hier liegt das eigentlich Problem.
Die erste Zeile kannst du direkt löschen (was auch immer du damit bezwecken möchtest), da die 2. Zeile dafür sorgt, dass du innerhalb der Schleife nicht mehr darauf zugreifst. Generell ist das nicht so eine brilliante Idee innerhalb einer For-Schleife die Zählvariable (i) zu manipulieren. Füg mal deinem Array 'hallo' ein weiteres Element hinzu und schau, was passiert ;) Evtl. kommst du selber drauf, wieso du das i nicht anrühren solltest. Als kleiner Tipp, schau dir mal den Schleifenkopf an.

Vorausgesetzt in der RTB soll 1\n2\n3\n4\n stehen, könntest du es mit einer For-Schleife so lösen.
Code:
private void button1_Click( object sender, EventArgs e )
{
  string[] hallo = {"1", "2", "3", "4"};
  string amx = "";

  for ( int i = 0; i < hallo.Length; ++i )
  {
    amx += hallo[i] + "\n";
  }

  richTextBox1.Text = amx;
}


lxlox schrieb:
Code:
        private void button1_Click(object sender, EventArgs e)
        {          
             string[] hallo = {"1", "2", "3", "4"};
            int i=0;
            string amx = "";
            richTextBox1.Text = "";
            while (true)
            {
                try
                {
                    hallo[i] += i + 0;
                    i++;
                    amx += hallo[i] + "\n";
                    richTextBox1.Text = amx;
                }
                catch
                { break; }
            }            
        }
    }
}

Nun, hier fehlen mir glatt die Worte ;)
Den Fehler aus der 1. Schleife hast du hier entdeckt und durch die denkbar schlechteste Lösung behoben ;)
Aber von vorne.
Zum einen ist die Bedingung true nicht grade die beste, die du hättest nehmen können. Du hast ein Array mit einer abzählbaren Anzahl an Elementen, hier 4. Da bietet es sich doch an, auch nur 4 Schleifendurchläufe zu vollziehen ;)
Code:
while( i < hallo.Length )

Code:
hallo[i] += i + 0;
i++;
amx += hallo[i] + "\n";
richTextBox1.Text = amx;
Gleiche Problem wie oben. Die zweite Zeile verhindert, dass die Erste irgendwo Verwendung findet. Weiterhin ist sie der Grund dafür, dass du eine Exception fangen musst (das meinte ich mit denkbar schlechteste Lösung). Im 4. durchlauf erhöhst du i auf 4 und somit bist du ausserhalb der Array-Grenzen. Try-Catch dient zur Fehlerbehandlung und nicht dazu, um aus einer unendlich laufenden Schleife auszusteigen ;)

Ich geb dir einfach mal eine korrektere Lösung:
Code:
private void button1_Click( object sender, EventArgs e )
{
  string[] hallo = {"1", "2", "3", "4"};
  int i = 0;

  string amx = string.Empty;
  while ( i < hallo.Length )
  {
    amx += hallo[i] + "\n";
    i++;
  }

  richTextBox1.Text = amx;
}

Auch hier wird nur 1\n2\n\3\n\4n in die RTB geschrieben.
Für den Fall, dass du noch die eine oder andere Zahl an jede Zeile anhängen möchtest, kannst du dir ja jetzt überlegen, wie du den Code ändern musst, damit es klappt.

Wenn du wirklich nur den Inhalt des Arrays in die RTB schreiben möchtest, kannst du das aber auch einfach haben. string.Join wurde hier schon erwähnt.

Code:
private void button1_Click( object sender, EventArgs e )
{
  string[] hallo = {"1", "2", "3", "4"};
  richTextBox1.Text = string.Join( "\n", hallo );
}

Oder direkt ohne Array
Code:
private void button1_Click( object sender, EventArgs e )
{
  richTextBox1.Text = string.Join( "\n", Enumerable.Range( 1, 4 ) );
}
 

Ähnliche Themen

Zurück
Oben