C# Frage

Michael-D

Cadet 3rd Year
Registriert
Nov. 2023
Beiträge
35
Schönen guten Tag zusammen,

ich habe mich bewusst hier angemeldet, da ich in den letzten Tagen bei der Googlesuche immer mal wieder auf dieses Forum gestoßen und musste auch manchmal etwas schmunzeln, dass so einige Mitglieder hier etwas in der Art "... Hausaufgaben werde nier nicht gemacht..." geschrieben haben. Kann ich absolut verstehn und mit 54 Jahren geht es auch manchmal etwas langsamer und brauch auch keine Hausaufgaben mehr zu machen. Ist ja auch schon 40 Jahre her :D

Ich habe vor einigen Wochen mich mit der C# Programmierung befasst, da ich mich schon seit langer Zeit über die Hardware und deren Infos brennend interessiere. Ich versuche immer, Probleme selbst zu lösen oder es zu versuchen - so weit es geht. Aber hier gehts im Moment absolut nicht mehr und OOP ist schon echt der Hammer :pcangry: Einiges Grundwissen von TP aus den 90-er jahren habe ich noch, aber das reicht bei weitem nicht mehr und tue ich mich schon etwas schwer, was OOP angeht. Dabei fange ich ja gerade erstmal an :(

Basierend auf der Seite von Microsoft unter DriveInfo.GetDrives Methode werden vorhandene Laufwerke per System.IO abgefragt. Ich habe im Internet etwas Interessantes über Laufwerkstyp per .NET-Framework ermitteln gefunden.

Was mich interessiert ist, warum man einen Zähler (int counter = 0; ) für die Anzahl der Laufwerke nicht außerhalt der foreach Schleife platzieren kann. Hier ein Beispiel...

Code:
class Program
    {
        static void Main(string[] args)
        // private void Main(string[] args)
        {
            int counter = 0;     // Zähler für die Anzahl Logischer Laufwerke
            // counter++;       // Zähler um +1 erhöhen - funktioniert aber nicht!

            Console.WriteLine("Vorhandene Logische Laufwerke..." + counter); // Das funktioniert nicht!!!

            Console.WriteLine("\n");    // Zeilenvorschub

            foreach (DriveInfo di in DriveInfo.GetDrives())
            {
                // Console.WriteLine("Vorhandene Logische Laufwerke...");
                counter++;  // Zähler um +1 erhöhen
                Console.WriteLine("Laufwerk: " + "{0} Typ: {1}", di.Name, di.DriveType.ToString());
            }

            Console.WriteLine("\nVorhandene Logische Laufwerke..." + counter); // Das funktioniert!!!
            Console.WriteLine("\n[Enter] zum Beenden drücken...");  // ESC Sequenz '\n' LF setzen
            Console.ReadLine(); // Auf Tastendruck warten

        } // end Static Void
    } // end Class

Nun frage ich mich aber, warum das denn nicht so funktioniert...
Code:
Console.WriteLine("Vorhandene Logische Laufwerke..." + counter); // Funktioniert nicht!

Könnte es sein, dass die Variable counter nicht im sogenannten Scope (Gültigkeitsbereich) ist? Bedeutet das , das eine Variable immer nur innerhalb der geschweiften Klammer gültig ist? Das heißt aber auch, das außerhalb der geschweiften Klammer nicht auf diese Variable zugegriffen werden!

Setze ich die Variable counter innerhalb der foreach Schleife, dann funktioniert es!
Code:
Console.WriteLine("\nVorhandene Logische Laufwerke..." + counter); // Das funktioniert!!!

Das ist dann die Bildschirmausgabe... Oben steht der Wert 0 - unten dann auch richtig der Wert 6
Vorhandene Logische Laufwerke...0

Laufwerk: C:\ Typ: Fixed
Laufwerk: D:\ Typ: Fixed
Laufwerk: E:\ Typ: Fixed
Laufwerk: F:\ Typ: Fixed
Laufwerk: G:\ Typ: Fixed
Laufwerk: H:\ Typ: Fixed

Vorhandene Logische Laufwerke...6

[Enter] zum Beenden drücken...

Könnte mir denn mal jemand BITTE sagen, was hier falsch ist? Variable auf "Global" setzen ? Wie denn? Vielleicht bin ich ja auch etwas kleinkariert, aber mich würde schon sehr interessieren, warum das so nicht geht!

Ich bedanke mich schon jetzt für Eure Vorschläge und bedenkt... "Ich bin noch Anfänger" ;)

Gruß aus der Eifel (bei Köln)
 
Lösung
Hier noch einmal eine Zusammenfassung, wie bei mir der Code aussehen würde (im Sinne einer einfachen Konsolenanwendung):
C#:
class Program
{
    static void Main(string[] args)
    {
        int AnzahlLaufwerke = DriveInfo.GetDrives().Count();
  
        Console.WriteLine($"Vorhandene Logische Laufwerke... {AnzahlLaufwerke}");
        Console.WriteLine("\n");

        foreach (DriveInfo di in DriveInfo.GetDrives())
        {
            Console.WriteLine($"Laufwerk: {di.Name} Typ: {di.DriveType.ToString()}");
        }

        Console.WriteLine("\n");
        Console.WriteLine("Beliebige Taste zum Beenden drücken...");
        Console.ReadLine();
    }
}

Ausgabe sähe dann wie folgt aus:
Code:
Vorhandene Logische Laufwerke... 6...
Willkomen im Forum,
der Scope von Deiner counter Variable ist innerhalb der geschweiften Klammer von der Main() Methode.
Du kannst Sie auch außerhalb der foreach-Schleife setzen.

Nur um Missverständnissen vorzubeugen, hast Du beim Testen auch die 2 Slashes vor counter in Zeile 7 entfernt?
C#:
// counter++;       // Zähler um +1 erhöhen - funktioniert aber nicht!
counter++;       // Zähler um +1 erhöhen - funktioniert aber nicht!
 
  • Gefällt mir
Reaktionen: Michael-D
So ganz verstehe ich das nicht die Ausgabe von counter ist doch korrekt?

Zuerst setzt Du counter auf 0 und gibst den Wert zu dem Zeitpunkt aus => 0
Dann zählst Du counter in der Schleife hoch und gibst wieder aus - der ist dann zu dem Zeitpunkt nach dem hochzählen halt bei der zweiten Ausgabe 6

das ist doch alles ganz genau so wie es sein sollte?

Oder ist der Code Ausschnitt oben schon irgendwie verändert?

Dass das Programm

0
....
6

ausgibt ist doch das was sein MUSS bei dem Code?
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Michael-D
Du kannst zu einer Zeichenkette (string) nicht einfach eine Zahl (int) addieren. Das was du willst ist das Zeichen '1' für die Zahl 1 an der Stelle ausgeben. Dazu kannst du z.B. String Interpolation nutzen.

C#:
Console.WriteLine($"\nVorhandene Logische Laufwerke...{counter}");

edit:
Das geht scheinbar doch, aber sauberer ist es mit Interpolation.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Michael-D
mental.dIseASe schrieb:
Hast du die Zeile 7 auskommentiert, um irgendwas zu demonstrieren? Ansonsten wäre es ja kein Wunder, dass das nicht geht...
Hab ich extra gemacht, da es nicht funktioniert! Kommentiere ich Zeile 7 aus (also entferne die // Slashes und führe das Programm aus, steht dort... Vorhandene Logische Laufwerke...1. Also das bringt so nichts.

;) Danke für Die Antwort
 
Äh ja was soll denn da sonst zu dem Zeitpunkt da ausgegeben werden?

Wenn du da counter ausgibst ist der halt noch 0 - oder wenn du denn um 1 mittels counter++ erhöht hast halt 1.
 
  • Gefällt mir
Reaktionen: Michael-D
michi.o schrieb:
Willkomen im Forum,
der Scope von Deiner counter Variable ist innerhalb der geschweiften Klammer von der Main() Methode.
Du kannst Sie auch außerhalb der foreach-Schleife setzen.

Nur um Missverständnissen vorzubeugen, hast Du beim Testen auch die 2 Slashes vor counter in Zeile 7 entfernt?
C#:
// counter++;       // Zähler um +1 erhöhen - funktioniert aber nicht!
counter++;       // Zähler um +1 erhöhen - funktioniert aber nicht!
Hi Michi,

das habe ich bewusst so gemacht, da es nicht funktioniert! Kommentiere ich Zeile 7 aus (also entferne die // Slashes und führe das Programm aus, steht dort... Vorhandene Logische Laufwerke...1. Also das bringt so nichts. Zumal ich doch dort einen Kommentar geschrieben hab, das es so nicht geht.

Danke für Die Antwort :)
 
Wenn Du die Anzahl der Laufwerke ausgeben willst BEVOR die Du die in der foreach Schleife nachgezählt hast müsstest counter halt entsprechend auf den korrekten Wert initalisieren.


Das was Du offensichtlich willst ist wohl das hier

Code:
class Program
{
    static void Main(string[] args)
    // private void Main(string[] args)
    {
        int counter = DriveInfo.GetDrives().Count();
        Console.WriteLine("Vorhandene Logische Laufwerke (per Count()) ..." + counter);
        Console.WriteLine("\n");    // Zeilenvorschub

        counter = 0;  // Reset Counter zum nochmal selber nachzaehlen

        foreach (DriveInfo di in DriveInfo.GetDrives())
        {
            // Console.WriteLine("Vorhandene Logische Laufwerke...");
            counter++;  // Zähler um +1 erhöhen
            Console.WriteLine("Laufwerk: " + "{0} Typ: {1}", di.Name, di.DriveType.ToString());
        }

        Console.WriteLine("\nVorhandene Logische Laufwerke (selber nachgezählt)..." + counter); // Das funktioniert!!!
        Console.WriteLine("\n[Enter] zum Beenden drücken...");  // ESC Sequenz '\n' LF setzen
        Console.ReadLine(); // Auf Tastendruck warten

    } // end Static Void
} // end Class
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Michael-D
Bohnenhans schrieb:
So ganz verstehe ich das nicht die Ausgabe von counter ist doch korrekt?

Zuerst setzt Du counter auf 0 und gibst den Wert zu dem Zeitpunkt aus => 0
Dann zählst Du counter in der Schleife hoch und gibst wieder aus - der ist dann zu dem Zeitpunkt nach dem hochzählen halt bei der zweiten Ausgabe 6

das ist doch alles ganz genau so wie es sein sollte?

Oder ist der Code Ausschnitt oben schon irgendwie verändert?

Dass das Programm

0
....
6

ausgibt ist doch das was sein MUSS bei dem Code?
Ok, gehen wirs anderes an...

Habe soeben in Visual Studio 2019 Pro mal ein Snapshot der Ausgabe direkt im Code gemacht. So sieht es im Anhang unten aus! Also bin ich doch nicht bekloppt. So einfach es das nämlich doch nicht.

Ich versuche es nochmal... (vielleicht klappt es jetzt besser:D)
Dort wo im Code oben steht "Vorhandene Logische Laufwerke..." dort sollte die Zahl 7 stehn und nicht 1.

Das wird auch so nicht funktionieren, da die Variable "counter" nicht im Scope (also im Gültigkeitsbereich) steht. Steht die Variable innerhalb der foreach Schleife, dann funktioniert das ganze auch!
Siehe "Vorhandene Logische Laufwerke...: 7"

Kann man es denn nicht so machen, das der Wert von von 7 auch oben steht? Versteht Ihr mich? Oder ich bin bekloppt...
 

Anhänge

  • Code_Console_Logical_Drives_2.png
    Code_Console_Logical_Drives_2.png
    50,2 KB · Aufrufe: 74
Aber wie soll denn da zu dem Zeitpunkt "7" (oder eigentlich "6") ausgegeben werden können?

Die Zahl counter=7 wird erst (zeitlich) später in den Zeilen 38 bis 44 auf den richtigen Wert gesetzt.
Erst DANACH kannst Du den Wert auch korrekt ausgeben.

Zeile 36+37 sind aber zeitlich VOR der korrekten Berechnung von counter.

C# kann viel - aber es kann nicht in der Zeit zurückspringen :D

Das hat alles rein gar nichts mit Gültigkeit und lokalen oder globalen Variablen zu tun oder mit OOP etc - counter ist sowieso funktionsglobal definiert - Du erwartest einfach ein korrektes Ergebnis ausgeben zu können, bevor Du das berechnest, und das ist das einzige Problem hier.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: fexxianosch
Ich versuche dir das mal ein wenig mehr im Detail zu erklären.
Ich verwende die Zeilenbeschriftung aus deinem Screenshot.

Code wird von oben nach unten abgearbeitet.

Die variable "counter" deklarierst und initialisierst du in Zeile 33:
C#:
int counter = 0;

Damit weis das Programm jetzt, wenn es Zeile 33 verarbeitet hat, dass in deinem Programm jetzt eine interne Variable "counter" mit dem wert 0 vorliegen hat, die im laufe des weiteren Programms zur Verfügung steht.

In Zeile 34 wird die Variable "counter" um 1 erhöht.
C#:
counter++;

Dieser Befehl "variable++" ist, vereinfacht ausgedrückt, nur eine Kurzschreibweise für:
C#:
counter = counter + 1;

Damit weis das Programm jetzt, wenn es Zeile 34 verarbeitet hat, dass die in deinem Programm zur Verfügung stehende Variable "counter" den wert 1 hat.

In Zeile 36 gibst du dann deinen Text inklusive des Inhalts aus "counter" in die Konsole aus.
C#:
Console.WriteLine("Vorhandene Logische Laufwerke..." + counter);

Zu diesem Zeitpunkt hast du noch nichts unter Zeile 36 verarbeitet und somit weis das Programm nur, dass "counter" immer noch 1 ist und gibt diesen dann auch so in der Konsole aus.

Von Zeile 38-44 führst du dann die "foreach"-Schleife aus.
C#:
foreach (DriveInfo di in DriveInfo.GetDrives())
{
    // Console.WriteLine("Vorhandene Logische Laufwerke...");
    counter++;  // Zähler um +1 erhöhen
    Console.WriteLine("Laufwerk: " + "{0} Typ: {1}", di.Name, di.DriveType.ToString());
}

Die "foreach"-Schleife funktioniert so wie jede "for( ; ; )"-Schleife es auch tut, nur mit dem unterschied, dass du der Schleife dein Array "bekannt" machst und C# sich dann selber um das durchlaufen kümmert.

Das Array, vom dem die Rede ist, wäre dann:
C#:
DriveInfo.GetDrives()
bzw. diese Funktion gibt dir besagtes Array zurück.

Nun durchläuft die Schleife jedes Element des Arrays, zählt dort die "counter"-Variable hoch und gibt Infos zu deinen Laufwerken aus:
C#:
counter++;  // Zähler um +1 erhöhen
Console.WriteLine("Laufwerk: " + "{0} Typ: {1}", di.Name, di.DriveType.ToString());

Erst währen des durchlaufens der Elemente wird die "counter"-Variable jeweils pro Element um 1 erhöht.

Zu Guter Letzt gibst du dann in Zeile 45 erneut den Text inklusive des Inhalts aus "counter" in die Konsole aus, der ja jetzt nach der Verarbeitung der Schleife immer erhöht wurde.

Somit kann der erste Text + counter aus Zeile 36 ja gar nicht wissen wie viele Laufwerke du da hast, da diese noch nicht in der Schleife verarbeitet wurden.

Lösungsvorschlag:
Um jetzt die Anzahl der Laufwerke vorab zur Verfügung zu haben, müssen wir die Anzahl der Elemente aus dem oben erwähnten Array schon vorher zur Verfügung stehen haben.

Das ließe sich wie schon von @Bohnenhans bereits erwähnt mit:
C#:
DriveInfo.GetDrives().Count()
bewerkstelligen.

Als Beispiel könntest du in Zeile 35 dann folgendes einfügen:
C#:
int AnzahlLaufwerke = DriveInfo.GetDrives().Count();
Das würde dir die Anzahl der Elemente des Arrays zurückgeben.

Zusätzlich müsste man dann in Zeile 36 folgende Anpassung machen:
Code:
Console.WriteLine("Vorhandene Logische Laufwerke..." + AnzahlLaufwerke);
Das würde dann, statt des Inhalts der "counter"-Variable, den Inhalt der "AnzahlLaufwerke"-Variable ausgeben.

Somit wäre die Möglichkeit gegeben, die erste Ausgabe von "Vorhandene Logische Laufwerke..." inklusive der Korrekten Anzahl der Laufwerke korrekt auszugeben.

für weitere Anpassungen kannst du natürlich gerne Fragen stellen und scheue dich nicht zu experimentieren... So habe ich das Programmieren auch gelernt :-)

Viele Grüße aus der vermeintlichen "Vor-Eifel" Aachen 😂
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Spock37, Michael-D und efcoyote
Nun aber grundsätzlich wichtig für ihn ist halt erstmal denke ich zu sehen, dass die Programme "atomar" halt trotz allem immer linear ausgeführt werden.

Und mögliche Änderungen von Variablenwerten in der Zukunft keine Auswirkung auf die Gegenwart oder Vergangenheit haben.

Ausser er hat evtl einen Quantenrechner da gibt es ja viel mehr "Gleichzeitig" :D das wird evtl noch interessant dann und da wird man sicher einiges wieder grundsätzlich neu und überdenken müssen :o

Der Anfang ist doch bei jedem immer etwas holprig, das doch normal, sonst wäre es doch auch langweilig.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Michael-D
Hier noch einmal eine Zusammenfassung, wie bei mir der Code aussehen würde (im Sinne einer einfachen Konsolenanwendung):
C#:
class Program
{
    static void Main(string[] args)
    {
        int AnzahlLaufwerke = DriveInfo.GetDrives().Count();
  
        Console.WriteLine($"Vorhandene Logische Laufwerke... {AnzahlLaufwerke}");
        Console.WriteLine("\n");

        foreach (DriveInfo di in DriveInfo.GetDrives())
        {
            Console.WriteLine($"Laufwerk: {di.Name} Typ: {di.DriveType.ToString()}");
        }

        Console.WriteLine("\n");
        Console.WriteLine("Beliebige Taste zum Beenden drücken...");
        Console.ReadLine();
    }
}

Ausgabe sähe dann wie folgt aus:
Code:
Vorhandene Logische Laufwerke... 6

Laufwerk: C:\ Typ: Fixed
Laufwerk: D:\ Typ: Fixed
Laufwerk: E:\ Typ: Fixed
Laufwerk: F:\ Typ: Fixed
Laufwerk: G:\ Typ: Fixed
Laufwerk: H:\ Typ: Fixed

Beliebige Taste zum Beenden drücken...

Ergänzung ()

Bohnenhans schrieb:
Nun aber grundsätzlich wichtig für ihn ist halt erstmal denke ich zu sehen, dass die Programme "atomar" halt trotz allem immer linear ausgeführt werden.

Und mögliche Änderungen von Variablenwerten in der Zukunft keine Auswirkung auf die Gegenwart oder Vergangenheit haben.
Naja, der 3. Satz in meinem Post :-)
 
Zuletzt bearbeitet:
Boooaaah Jungs Ihr seit absolute SPITZENKLASSE !!!!!!

Weiß überhaupt nicht wie ich Euch allen danken soll.

fexxianosch | Bohnenhans | efccoyote => Herzlichen Dank für Eure super Hilfe :schluck:



Muss mir das später mal in Ruhe anschauen und sage Euch Bescheid. Hab ich mir doch das richtige Forum ausgesucht ;)
 
fexxianosch schrieb:
Lösungsvorschlag:
Um jetzt die Anzahl der Laufwerke vorab zur Verfügung zu haben, müssen wir die Anzahl der Elemente aus dem oben erwähnten Array schon vorher zur Verfügung stehen haben.

Das ließe sich wie schon von @Bohnenhans bereits erwähnt mit:
C#:
DriveInfo.GetDrives().Count()
bewerkstelligen.
Und genau das ist der springende Punkt!!! Mit Arrays kenn ich mich NOCH nicht so aus, aber ich arbeite dran :D
Also nun funktioniert es! Erstklassige Arbeit und nochmal VIELEN DANK dafür.

Einen "Danke" Button gibts hier nicht, schade. Aber der "Gefällt mir" Button tuts auch :schluck:

PS Hab noch so viele Fragen. Kommt aber noch ;)

fexxianosch schrieb:
Viele Grüße aus der vermeintlichen "Vor-Eifel" Aachen 😂
Darf ich mal fragen von woher ? Kenn mich auch nicht so toll hier aus, da ich erst seit 5 Jahren hier wohne.
 
Michael-D schrieb:
PS Hab noch so viele Fragen. Kommt aber noch ;)
Es ist noch kein Meister vom Himmel gefallen...
Ich arbeite jetzt seit ca. 10 Jahren als Softwareentwickler und ich kenn mich nur in einem "winzigen" Bereich aus. IT ist seeehr Facettenreich!

Michael-D schrieb:
Darf ich mal fragen von woher ? Kenn mich auch nicht so toll hier aus, da ich erst seit 5 Jahren hier wohne.
Naja, aus Aachen.
Wird manchmal lustigerweise auch als Vor-Eifel betitelt.
 
Zuletzt bearbeitet:
fexxianosch schrieb:
Es ist noch kein Meister vom Himmel gefallen...
Ich arbeite jetzt seit ca. 10 Jahren als Softwareentwickler und ich kenn mich nur in einem "winzigen" Bereich aus. IT ist seeehr Facettenreich!
Dann hab ich ja genau die richtigen Jungs hier ;)

Früher war einiges viel einfacher. Da gab es nur DOS 5 und Windows 3. Programmiert wurde damals nur auf BIOS Basis, wenn es um Hardware Info ging. Da gab es auch noch kein Net Framework oder CLR. Ich glaub die kam erst Anfang 2000. Da gab es auch kein VS sondern u.a. schönes QB oder PAS. Ach war dat schön :D
 
Was mir am Anfang sehr geholfen hat, war die Möglichkeit, das Programm schrittweise auszuführen. Viele Anfänger scheinen die Funktion gar nicht zu kennen.

Einfach mal in Visual Studio F10 drücken, um das Programm zu starten. Du kannst dann mit der Maus auf die Variablen im Code zeigen und den aktuellen Wert sehen. Mit jedem Druck auf F10 läuft das Programm einen Schritt weiter.
 
  • Gefällt mir
Reaktionen: Michael-D

Ähnliche Themen

Zurück
Oben