Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Mit foreach- und for-Schleifen über ein Array iterieren
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

Mit foreach- und for-Schleifen über ein Array iterieren

beantworten | zitieren | melden

Ich grüße euch liebe Community,

ich mache mit dem Lernen von C# über das Buch "Schrödinger Programmiert" vom Rheinwerke Verlag gute Fortschritte und habe mich nun erfolgreich durch den Dschungel von Datentypen, boolschen Ausdrücken und co. gekämpft

Bevor es im Buch nun mit objektorientiertem Programmieren los geht, werde noch Arrays (sowohl klassische, als auch Strings an sich) und Schleifen behandelt.

Soweit verstehe ich dies auch ohne Probleme, allerdings habe ich aktuell noch eine grundlegende Verständnisfrage, um zu wissen, ob ich hier auf der richtigen Spur bin (keine Sorge, ich werde in den nächsten Tagen wohl noch mal auf String und co. hier zurückkehren ). Nun aber zur Frage und Ausgangssituation:


1. Ich baue mir ein ganz normales, beliebiges Array mit ein paar Zahlen drin.


int[] meinArray = new int [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15 };

2. Nun möchte ich die Werte aus diesem Array ausgeben. Dazu nutze ich nun einmal die foreach Schleife wie folgt.


foreach (int meinWert in meinArray) {
				Console.WriteLine (meinWert);

			}

-> Wenn ich dies nun korrekt verstehe wird eine Variable vom Typ int (in dem Fall "meinWert") dem Array "meinArray" übergeben, nimmt jeden einzelnen Wert in diesem Array an und gibt diesen über die Konsole aus, sodass ich weiß, welche konkreten Werte ich in diesem Array geparkt habe, richtig?

3. Nun gibt es im Buch auch noch eine Möglichkeit etwas ähnliches mit einer for Schleife zu bauen, nämlich so.


for (int i = 0; i < meinArray.Length; i++) {
				Console.WriteLine (i);

			}

-> Wenn ich es richtig verstehe wird hier natürlich nicht wie bei foreach jeder Wert konkret in der Konsole abgebildet, sondern nur der Index ausgegeben, bis wohin / an welcher Stelle Werte (welche auch immer) gespeichert sind.


Ist mein Gedankengang soweit korrekt?

Danke im Voraus und ganz lieben Gruß,

Lalgeriano
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Lalgeriano am .
private Nachricht | Beiträge des Benutzers
bredator
myCSharp.de - Member



Dabei seit:
Beiträge: 368

beantworten | zitieren | melden

Ja, dein Gedankengang ist korrekt. Es sollte heißen:


for (int i = 0; i < meinArray.Length; i++) 
{
    Console.WriteLine (meinArray[i].ToString());
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von bredator am .
private Nachricht | Beiträge des Benutzers
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

Vielen Dank!

Wieso wäre in diesem Beispiel "ToString" von Bedeutung? Im Buch wird die Methode "ToString" erst im kommenden Kapitel abgehandelt und noch nicht an dieser Stelle.

Ich weiß durch lesen aber nun, dass diese Methode die Ausgabe, in diesem Fall, in einen String umwandelt. Wieso wäre dies in diesem Beispiel ratsam? Oder ist dies eher einer Konvention, der man generell folgen sollte?

Lieben Gruß



EDIT:

Habe die Ausgabe nun nochmal mit dem ToString zusätzlich gemacht. Jetzt kommt ja aber eins zu eins das selbe raus wie bei der foreach Schleife. Warum eigentlich?

Die Ausgabe sieht so aus:
Zitat
1
2
3
4
5
6
7
8
9
10
15

Bei der Ausgabe mit dem i ohne ToString sah sie so aus:
Zitat
0
1
2
3
4
5
6
7
8
9
10

Durch das ToString würde ich doch den selben Effekt mit einer for Schleife schaffen, den die foreach auch hat oder? Also jeden konkreten Wert auslesen.

Mit der for Schleife ohne das ToString bekomme ich ja aber den Index angegeben, also beginnend bei 0 und ohne die 15, da es ja genau 11 Werte sind.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Lalgeriano am .
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Das ToString() kannst du an dieser Stelle auch weglassen, weil du die Methode Console.WriteLine(object) aufrufst (und die wiederum, von dir unbemerkt, sowieso das ToString() des Objekts aufruft. Also musst du das nicht machen).

Ansonsten gibst du das eine mal die Zählvariable aus, und das andere Mal den Inhalt deines Arrays an der Stelle, die die Zählvariable gerade beschreibt.

Die folgenden Schleifen sind identisch:


//eins
for (int i = 0; i < meinArray.Length; i++)
{
    Console.WriteLine (meinArray[i]);
}
//zwei
foreach(var meinWert in meinArray)
{
    Console.WriteLine(meinWert);
}
//drei, damit du siehst, dass man beim programmieren immer mehrere Möglichkeiten hat
meinArray.ToList().ForEach(Console.WriteLine);

LaTino
das Buch wird mir immer unsympathischer.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von LaTino am .
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
bredator
myCSharp.de - Member



Dabei seit:
Beiträge: 368

beantworten | zitieren | melden

Jo, kann man auch weglassen, weils von der Methode richtig umgewandelt wird. In anderen Fällen wird das nicht automatisch gemacht, drum schreibe ichs immer dazu.
private Nachricht | Beiträge des Benutzers
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

Alles klar, das erklärt dann einiges, danke für die Hilfe Jungs
Zitat
Ansonsten gibst du das eine mal die Zählvariable aus, und das andere Mal den Inhalt deines Arrays an der Stelle, die die Zählvariable gerade beschreibt.

Ist dies dann auch der Grund, wieso ich bei der normale for Ausgabe die Indizes von 0-10 als Ausgabe bekomme und mit der for Schleife und dem ToString den Inhalt?

P.S: Ich muss sagen, dass ich mit dem Buch soweit schon ganz gut lernen kann und einen recht einfachen und guten Einstieg bekomme. Das mal Fragen auftauchen ist ja recht normal, ergänzende Lektüre oder ein gutes Forum wie dieses hier, ist glaube ich immer unverzichtbar
private Nachricht | Beiträge des Benutzers
Lothi
myCSharp.de - Member

Avatar #avatar-2631.jpg


Dabei seit:
Beiträge: 350
Herkunft: Schweiz

beantworten | zitieren | melden

Nein.
Du gibst beide male eine andere Variable aus.


//Mein Wert ist das Objekt in der Liste.
//Beim Aufruf wird automatisch ToString() aufgerufen.
foreach (int meinWert in meinArray) {
                 Console.WriteLine (meinWert);

             } 


//i ist eine int Variable die du im Schleifenkopf deklariert hast.
//Du gibst einfach nur i aus 
//siehe im Buch for - Schleifen
for (int i = 0; i < meinArray.Length; i++) {
                 Console.WriteLine (i);

             } 


Gruss Lothi
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15671
Herkunft: BW

beantworten | zitieren | melden

ToString() ist eine Standard-Methode von Object, von dem quasi alles erbt. Es stellt die absolute Spitze der Typhierarchie dar.
Bei allen Umwandlungen auf String wird im Hintergrund <object>.ToString() ausgeführt, sodass auch ein

Int32 n = 1;
String output = "Nummer: #" + n;
Genauso valide ist wie

String output = "Nummer: #" + n.ToString();

Das ist in anderen Sprachen durchaus anders; C# ist aber eine relativ effiziente Sprache, verglichen mit anderen Hochsprachen.
Du wirst also an vielen Stellen auf solche und ähnliche Bequemlichkeiten treffen.

PS: Du hast auch die Möglichkeit, die Rückgabe von ToString() bei eigenen Klassen selbst zu definieren (durch Überschreiben der Standardmethode).

Lass Dich auch von solchen Aussagen nicht verunsichern.
Das Buch gehört wirklich zu den besseren. Unsere Azubis / Studenten arbeiten ebenfalls teilweise damit und machen gute Fortschritte.
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2111

beantworten | zitieren | melden

Sieh es so.
Die for Schleife zählt über den Index. Allgemein gesagt zählt die einfach nur Zahlen hoch. Was du mit denen dann tust ist ihr egal, in dem Fall nimmst du sie um vom Array das i-te Element auszulesen.

foreach geht durch die Elemente des Arrays. foreach = "für jedes" Element im Array ... gib das in der Variablen zurück. Indexe zurückgeben wäre ziemlich langweilig denn die gehen von 0 bis Length - 1.
private Nachricht | Beiträge des Benutzers
OlafSt
myCSharp.de - Member



Dabei seit:
Beiträge: 71
Herkunft: HH

beantworten | zitieren | melden

Am besten sieht man den Unterschied, wenn man den Inhalt des Arrays umdreht:

int[] meinArray = new int [] { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };


Läßt du dieses Array durch die beiden Originalschleifen laufen, siehst du deutlich, was anders läuft.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von OlafSt am .
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Nein, am deutlichsten würde man das sehen, wenn das Array gar nicht vom Typ int[] wäre, und, ganz ehrlich, wenn das Buch für Anfänger ist, dann hätte man das dort auch so machen müssen und nicht Inhalte verwenden, die den Keys fast aufs Haar gleichen.

LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

So, erst einmal nochmal vielen lieben Dank für die Hilfe und Erklärungen


1. Ich habe mir nun das Array von OlafSt zu Herzen genommen und dort einmal eine for- und eine foreach-Schleife durchlaufen lassen, ähnlich wie die im Ausgangsbeitrag. Nun bekomme ich beides mal die Zahlen von 1 bis 15 ausgespuckt. Die for-Schleife scheint mir nun allerdings keinen Index mehr auszugeben, da dieser ja von 0 bis ausschließlich 14 laufen sollte? Ich glaube, da habe ich irgendwo noch einen Denkfehler. [EDIT: Hat sich erledigt, muss ja die Laufvariable und nicht das Array ausgeben. Habe da zu schnell getippt und zu wenig nachgedacht ]

2. Ich habe im Buch nun Methoden für den String abgearbeitet, sprich "Funktionen" wie Trim, IndexOf, Split und so weiter und so fort. Soweit ist auch alles klar. Gibt es auch eine Möglichkeit (rein theoretisch) Leerstellen mitten im Text zu entfernen, sodass der Satz komplett zusammen hängt? Mit Trim kann ich ja lediglich Leerzeichen am Anfang oder Ende entfernen.

3. Auch wurden die Methoden mit String Builder / Append und String.Format behandelt. Bei String.Format war nun folgendes, konkretes Beispiel angegeben:


string text = "Schrödinger ist cool";
int len = text.length;
string [] words = text.Split (' ');
string newText = string.Format ("Die Länge: {0}. Anzahl der Wörter: {1}", len, words.length);

Soweit ist es mir auch klar und verständlich. Nun wird in der letzten Zeile allerdings die Funktion Format aufgerufen um den nachfolgenden String eben zu formatieren. Ich sehe allerdings absolut keinen Unterschied zu dieser letzten Zeile und zu einer Zeile mit Console.WriteLine () und dann eben den Text mit Platzhaltern. Wo wäre dort genau der Unterschied? (Im Buch wird erwähnt, dass es generell keinen Sinn macht konstante String Werte mit String.Format auszugeben, es soll nur zur Veranschaulichung dienen).

4. Eine Aufgabe war es nun, einen eingegebenen Text rückwärts in eine neue Variable zu speichern und auszugeben. Dort wurde nun folgende Lösung präsentiert, wo ich ein wenig Probleme habe, diese richtig nachzuvollziehen. Meine Gedankengänge füge ich mal als Kommentar hinter der Zeile an.


Console.WriteLine ("Text eingeben");
string text = Console.ReadLine ();
string neuerText = "";

char [] inverted = new char [text.length]; // es wird ein char Array angelegt, das so groß ist, wie der Text lang.
for (int i = 0; i < inverted.Length; i++) // Die Schleife läuft bis i < inverted.Length weil es sonst über die Länge hinaus laufen würde? 
{ inverted [i] = text [inverted.Length - 1 - i] } // Die Zeile verstehe ich nicht ganz.  
neuerText = new String (inverted); // Die Var. neuerText bekommt quasi das Ergebnis aus der Variable inverted geliefert.
Console.WriteLine ("Der invertierte Text: {0}", neuerText);

5. Es kam Nullable dran. Wenn ich dies richtig verstehe, werden nur Datentypen wie bool, char oder Zahlen mit einem ? nullable gemacht. Wenn ich einen String nicht zuweisen will, klappt dies nicht über ein ? sondern mit der methode String.Empty oder einfach mit "" - ist das soweit korrekt?

6. Angenommen ich baue nun folgendes:


int? meinInt = null;
int meinNeuerInteger = meinInt.Value

Vorweg: Ich habe verstanden, dass die Methode .Value den tatsächlichen Wert abbildet, den, in diesem Fall meine Variable meinInt, besitzt. In diesem Fall würde dies zu einem Fehler führen, da meinInt = null ist.

Würde meinInt nun einen Wert enthalten, beispielsweise die Zahl 10. WIESO sollte ich dann mit der Methode .Value darauf zugreifen und diese nicht einfach über Beispielsweise Console.WriteLine (meinInt) auslesen? Wo befindet sich der konkrete Unterschied? Ich bekomme doch in beiden Fällen den Wert, den meine Variable enthält, ausgegeben, oder?




So, das wären nun erstmal meine weiteren Frage. Langsam wird's wohl peinlich mit der Fragerei Aber oft ist die Hilfe von Personen, die sich selbst in der Materie befinden und es nachvollziehen können hilfreicher als begleitendes Material wie Videos oder nur das Buch

Lieben Gruß und schonmal danke für die Mühe!

Lalgeriano
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Lalgeriano am .
private Nachricht | Beiträge des Benutzers
DerKleineTomy
myCSharp.de - Member



Dabei seit:
Beiträge: 106

beantworten | zitieren | melden

2. Um Leerzeichen mitten aus einem String zu entfernen, bietet sich z.B. String.Replace an.


string textWithWhitespace = "This text has whitespaces"
string textWithoutWhitespace = textWithWhitespace.Replace(" ", ""); // Leerzeichen " " durch nichts ersetzen ""

3. Die Antwort gehört auch teilweise zu 6.: Du solltest nicht immer nur auf die Ausgabe mit Console.WriteLine() achten. Willst du z.B. den string NICHT ausgeben und nur in einer Variablen speichern, oder willst du ihn für die SPÄTERE Ausgabe zwischenspeichern, dann kommst du um String.Format() nicht drumherum. Console.WriteLine() benutzt im Hintergrund nichts anderes als String.Format.

4. text.Length ist die Anzahl der einzelnen Chars im String. Da aber ein Array generell mit Index 0 und nicht 1 anfängt, musst du bei der For-Schleife von 0 bis text.length - 1 zählen. Hat dein String z.B. Length 10, dann ist der höchste Index 9 und nicht 10.

for (int i = 0; i < inverted.Length; i++)
{ inverted [i] = text [inverted.Length - 1 - i]; }
Es geht ja darum, dass der Text invertiert, also von hinten nach vorne, gespeichert wird. Du willst also deinen Text von hinten nach vorne durchlaufen, also fängst du mit dem höchsten Index an (inverted.Length - 1) und ziehst dann i ab. In anderen Worten, du zählst runter und nicht rauf. Übrigens finde ich an dieser Stelle [text.Length - 1 - i] etwas schöner, aber macht keinen Unterschied, da text.Length == inverted.Length ist.

5. Nullable ist nur für Wertetypen gedacht. Alle Referenztypen (darunter auch String) können bereits den Wert null annehmen. Was der Unterschied von Referenz- und Wertetypen ist, wird vermutlich noch später in dem Buch behandelt (wenn noch nicht geschehen).
Dementsprechend ist ein nicht zugewiesener String tatsächlich einfach:

string nullString = null;
string emptyString = String.Empty; // oder ""
Beachte, dass ein leerer String anders ist, als ein null-String.

6. Wie in 3. bereits angesprochen: Wenn du die Zahl nur ausgeben willst, dann macht es keinen Unterschied, aber wenn du den tatsächlichen Wert zwischenspeichern willst, dann schon. Z.B. macht auch folgendes keinen Unterschied bezüglich der Ausgabe, ist aber inhaltlich schon etwas anders:

string myNumber = "5";
int myNumber2 = 5;
long myNumber3 = 5;
Console.WriteLine(myNumber);
Console.WriteLine(myNumber2);
Console.WriteLine(myNumber3);
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von DerKleineTomy am .
private Nachricht | Beiträge des Benutzers
Ezio
myCSharp.de - Member

Avatar #avatar-3575.png


Dabei seit:
Beiträge: 196

beantworten | zitieren | melden

Hallo LaIgeriano,

zu 3. könnte dich [Artikel] Strings verketten: Performance-Betrachtung interessieren.

zu 5. zu dem, was DerKleineTomy geschrieben hat:
"null" bedeutet, dass deine Variable auf keinen Speicherbereich verweist und somit gar keinen Wert haben kann.
"" bzw. string.Emty bedeutet dagegen, dass die Variable auf einen Speicherbereich verweist, der eine leere Zeichenkette bzw. eine Zeichenkette der Länge 0 enthält.
Ist genauso ein Wert wie bei int die Zahl 0.
[FAQ] Besonderheiten der String-Klasse (immutabler Referenztyp mit Wertsemantik) Könnte dich dazu interessieren.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Ezio am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15671
Herkunft: BW

beantworten | zitieren | melden

Bezüglich Performance sollte man es nicht übertreiben. Sich damit intensiv zu beschäftigen sollte man erst, wenn es wirklich ein Problem gibt.
Aber das sollte nicht die Planung oder Architektur initial bei stink normalen Anwendungen beeinflussen.

String ist besonders.
Why .NET String is immutable?
Das wird aber auch in jedem Buch behandelt.

Es tut Dir gut dran, wenn Du ein Buch erstmal durcharbeitest.
Ansonsten liest Du hier und im Buch die Dinge doppelt. Und das kann man ja vermeiden ;-)
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Zitat von Abt
Bezüglich Performance sollte man es nicht übertreiben. Sich damit intensiv zu beschäftigen sollte man erst, wenn es wirklich ein Problem gibt.

Sorry, aber das scheint mir ein wenig blauäugig. Wenn man nie gelernt hat, wieso und vor allem wann string concatenation ein ernstes Problem werden kann, und wie man erkennen kann, wo das grundlegende Problem noch auftreten kann, dann wird man früher oder später schlechten Code schreiben. Das kann man Anfängern nicht früh genug erklären. (Und mit erklären meine ich nicht "nimm einfach immer stringbuilder, dann passiert nichts, wieso, ist egal". Wenn man weiß, was man tut, kann man auch, genau wie du schreibst, entscheiden, wann man übertreibt und wann nicht. Aber Anfänger können das nicht!)
http://www.joelonsoftware.com/articles/fog0000000319.html

Must. Read.

LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15671
Herkunft: BW

beantworten | zitieren | melden

Ich hab gewusst, dass Du darauf antwortest - das war vorhersehbar; auch der Inhalt.
Wer sich über String.Concat schon vor dem Schreiben der Anwendung Gedanken macht, der hat in meinen Augen ein fragwürdiges Vorgehen.

Gerade Anfänger machen "viel größere Fehler" als Performance-Issues bei String.Concat; zB wann welcher Art von Liste / Array verwendet werden sollte.
Soviel zum Thema Back to Basics (und must read ist auch was andres).

Du kannst Deinen Anfängern ja auch sagen, sie sollen lieber for() statt foreach() nehmen, da es 0.002% schneller ist - dafür eben eine 30% höhere Wahrscheinlichkeit einer IndexRange-Verletzung erzeugen.
Na wo da die Prioritäten wohl liegen... das kann man nicht früh genug beibringen ([/Ironie] ) 8)
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Nunja. Es reicht völlig, darauf hinzuweisen, dass es ein Problem geben könnte. Wenn es dann eins gibt, sucht man nicht endlos. Niemand verlangt, dass jeder Anfänger erst einmal Zeichenketten in C kennt, bevor er loslegt. Nur "mach dir keine Sorgen" endet in dem Fall nicht gut. String-Verkettung ist nunmal eins von den Problemen, die nicht unbedingt sofort als solche zu erkennen sind.

Und wie du oben sehen kannst, habe ich neben for und foreach auch .ForEach empfohlen. Ich sehe da also keinen Grund für Sarkasmus.

LaTino
Edit: ich habe als C#-Anfänger auch foreach() { string += ... } benutzt, ohne mir Gedanken zu machen, _obwohl_ ich von C kam. C# versteckt das Problem einfach sehr gut.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von LaTino am .
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

Hallo Leute,

erst einmal vielen Dank für die Hilfe und eure Erklärungen, speziell an DerKleineTomy und Ezio.
Die Erklärungen haben mir doch schon einmal sehr weiter geholfen und mein Verständnis vertief.

Ich merke auf jeden Fall, dass ich nicht immer nur sehr oberflächlich denken und von einer Konsolenausgabe ausgehen soll

Dank euren Beispielen und Erklärungen blicke ich nun langsam in den angeführten Themen durch und arbeite mich vor, nochmals ein riesengroßes Dankeschön, dass ihr euch durch meine wohl (für euch) eher mühseligen Fragen arbeitet

Bezüglich der Performance @ LaTino und Abt: Ich werde mal ein Auge auf die performance technischen Seiten halten, mich dennoch wohl erst einmal konkret auf die Grundlagen versteifen und schauen wie sie sitzen, das andere aber dennoch nicht komplett aus dem Auge lassen. Auch für diese Hinweise selbstverständlich noch einmal ein dickes Dankeschön! =)

Auch die Links von Ezio, abt und LaTino werde ich beherzigen und immer mal wieder drauf zurück schweifen und mein Verständnis soweit vertiefen.


Eine kleine Frage fällt mir grad aber noch ein: Bezüglich des String und der Zuweisung von null. Eventuell denke ich schon wieder zu weit oder einfach falsch um die Ecke. Wie Ezio erklärte, verweist ein String = null auf keinen Speicherbereich. Wieso wäre es also sinnvoll einen String = null zu setzen?

Wäre dies wie mit Objekten, die gelöscht werden können? Dass man diese quasi auf null setzt, damit der Garbage Collector bescheid weiß, dass er sie abbauen kann?

Nochmals danke im Voraus und einen guten Start in die Woche
private Nachricht | Beiträge des Benutzers
Palin
myCSharp.de - Member



Dabei seit:
Beiträge: 1115

beantworten | zitieren | melden

In den meisten Fällen wird ein String nicht Expliziet auf Null gesezt. Soviel Speicher verbraucht er nicht. ;)

Meistens hat man den umgekerten Fall, man Erzeugt ein Objekt mit Strings als Propertys (z.B. Name) und prüft dann ob der Wert Null ist um zu sehen, ob gewisse Werte gesetzt worden sind.
Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Zitat von Lalgeriano
Eine kleine Frage fällt mir grad aber noch ein: Bezüglich des String und der Zuweisung von null. Eventuell denke ich schon wieder zu weit oder einfach falsch um die Ecke. Wie Ezio erklärte, verweist ein String = null auf keinen Speicherbereich. Wieso wäre es also sinnvoll einen String = null zu setzen?

Wäre dies wie mit Objekten, die gelöscht werden können? Dass man diese quasi auf null setzt, damit der Garbage Collector bescheid weiß, dass er sie abbauen kann?

Der Garbage Collector räumt unabhängig vom Inhalt die Objekte auf, auf die kein Verweis mehr existiert. Wenn du ein bisschen über die Schnittstelle IDisposable googelst, findest du schnell ein Beispiel, mit dem du dir eine Ausgabe machen lassen kannst, sobald der GC zuschlägt - da sieht man dann schon, dass das recht schnell und gruendlich funktioniert. Eingreifen oder den GC bewusst dazu bringen, zu einem bestimmten Zeitpunkt ein Objekt aufzuräumen, ist nur in sehr spezifischen Fällen nötig (meistens mit unverwalteten Ressourcen: Dateien, Datenbankverbbindungen etc.).

Eine string-Variable null setzen...selten. Eventuell, wenn man später einen Vergleich machen will, ob die Variable immer noch null ist, oder was in der Art.

LaTino
EDIT: typos
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von LaTino am .
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

@LaTino: Danke für die nähere Erklärung! :-)

Ich habe noch mal eine Frage die teilweise auf den Strint Builder und das Append zutrifft. Und zwar lerne ich ab und an unterwegs (Uni, im Café oder wo auch immer) mit einem MacBook, da ich nur einen Desktop Computer mit Windows nutze.

Auf dem MacBook habe ich mir Xamarin Studio heruntergeladen und damit bis lang problemlos programmiert. Ich nutze dort die Mono 4.0.4 Runtime und habe auch immer fleißig Updates installiert.

Nun wollte ich ein wenig am MacBook mit dem StringBuilder und String Format üben. Letzteres ist auch kein Problem, beim String Builder bekomme ich hingegen immer einen Fehler, die ich mal als Kommentar in die Zeile packe.


StringBuilder builder = new StringBuilder(); //String Builder is a namespace but a type was expected
	// Append to StringBuilder.
	for (int i = 0; i < 10; i++)
	{
	    builder.Append(i).Append(" "); //a local variable builder cannot be used before declared
	}
	Console.WriteLine(builder); //a local variable builder cannot be used before declared


Am Desktop Computer mit Windows und Visual Studio 2015 klappt es ohne Probleme.

Hat jemand eine Ahnung wie es zu dieser Differenz und damit zum Fehler auf dem MacBook kommen kann? Als Betriebssystem läuft dort Yosemite.

Kurze Frage am Rande: Sollte man das String Format dem Strint Builder vorziehen? Geht's dabei eher um eine Glaubensfrage? Bin dort noch leicht hin und her gerissen.

Danke und lieben Gruß,
Lalgeriano
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

StringBuilder, um Zeichenketten zu erzeugen, die ggf. in einer Schleife o.ä. aufgebaut werden. StringBuilder is mutable, das heisst, der Inhalt kann verändert werden. String selbst ist immutable, dh. der Inhalt ist unveränderbar - wenn du also string a = "hello" + "world" machst, muss ein neues Objekt erzeugt werden und die Teilzeichenketten zeichenweise kopiert werden (daher der Hinweis mit Schleifen - dort wird das ganze dann relativ schnell spürbar langsamer).
Wenn man nur fix eine formatierte Zeichenkette erstellen will, reicht also string.format.

Zu deinem Problem: eventuell kann jemand mit mono-Erfahrung da Genaueres sagen, für mich sieht das einfach so aus, als ob der StringBuilder nicht referenziert ist - versuch mal vollständige Referenzierung mit System.Text.StringBuilder.

LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
private Nachricht | Beiträge des Benutzers
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

Hallo LaTino,

vielen dank für deine Hilfe/Erklärung und sorry für die etwas verspätete Antwort!

String Builder und String.Format verstehe ich dank der Erklärung nun deutlich besser, nochmals danke an der Stelle!

Zum Thema mit Xamarin. Mit deinem Tipp hat es geklappt! Über System.Text.StringBuilder lässt sich das Code ohne Probleme ausführen. Komisch, dass es anscheinend nicht korrekt referenziert wurde, so lange es aber so geht soll's mir egal sein Danke auch hierfür!

Lieben Gruß
Lalgeriano
private Nachricht | Beiträge des Benutzers
bb1898
myCSharp.de - Member



Dabei seit:
Beiträge: 110

beantworten | zitieren | melden

Zitat von Lalgeriano
Zum Thema mit Xamarin. Mit deinem Tipp hat es geklappt! Über System.Text.StringBuilder lässt sich das Code ohne Probleme ausführen. Komisch, dass es anscheinend nicht korrekt referenziert wurde, so lange es aber so geht soll's mir egal sein :) Danke auch hierfür!
Der Namensraum System.Text ist nicht von allein eingebunden. Im Visual Studio enthält eine Klassendefinition normalerweise schon von Anfang an die entsprechende using-Anweisung im Kopf:

using System.Text;

Das scheint am Anfang Deiner Klassendatei nicht zu stehen und dann musst Du halt den StringBuilder komplett mit Namensraum ansprechen. Oder, natürlich, Du ergänzt die Anweisung.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von bb1898 am .
private Nachricht | Beiträge des Benutzers
Lalgeriano
myCSharp.de - Member



Dabei seit:
Beiträge: 21

Themenstarter:

beantworten | zitieren | melden

Danke für den Hinweis @ bb1898. Mit deinem Tip klappt es ebenfalls super.
Da wäre ich spontan gar nicht drauf gekommen, manchmal sieht man den Wald vor lauter Bäume nicht und gleichzeitig ist's wohl noch meine Einsteiger-Naivität :D
private Nachricht | Beiträge des Benutzers