Laden...

foreach-Laufvariable bekommt einen Wert, der nicht in der Liste vorkommt

Erstellt von Fridoo vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.770 Views
F
Fridoo Themenstarter:in
47 Beiträge seit 2010
vor 13 Jahren
foreach-Laufvariable bekommt einen Wert, der nicht in der Liste vorkommt

Hallo zusammen
Ich habe gerade ein Problem an dem ich verzweifle...
Ich versuche die gesamte Ordnerstruktur mit der Konsole auszulesen...

Das unten angehängte Bild beschreibt mein Problem.
di1 wird aus meiner Sicht falsch gesetzt
//Siehe bei dem einzigen Kommentar im 2. Code abschnitt

edit:
Das angehängte Bild zeigt den Enumerator.
di1 ist die lauf variable die einen Wert zugewiesen bekommt der in der Liste nicht existiert.

nehmen wir an


cd = DirectoryInfo("D:\$RECYCLE.BIN");
DirectoryInfo[] dirs = cd.GetDirectories(); //wird nur für vereinfachtes Debuggen benötigt
dirFort = new Hashtable();
message = string.Empty;
tabs = "\t";


while (true)
{
    int cFort = ((int)dirFort[cd]) != null ? ((int)dirFort[cd]) : 0;
    foreach (DirectoryInfo di1 in dirs) // <-- Hier geschieht der Fehler
    {
        message += tabs + di1.Name + "\\\n";
        if (di1.GetDirectories().Length > 0)
        {
            cd = di1;
            dirs = cd.GetDirectories();
            if (!dirFort.Contains(cd)) dirFort.Add(cd, 0);
            tabs += "\t";
        }
        else
        {
            dirFort[cd] = ((int)dirFort[cd]) + 1;
        }
    }
    foreach (FileInfo f in cd.GetFiles())
    {
        message += tabs + f.Name + "\n";
    }
        if(cd.Parent == null) break;
    cd = cd.Parent;
    dirs = cd.GetDirectories();
    tabs = tabs.Replace("\t", "");
}

916 Beiträge seit 2008
vor 13 Jahren

Bescheib mal bitte dein Problem, ich für meinen Teil versteh es nämlich nicht.

Again what learned...

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo Fridoo,

sry die Frage, aber du weißt schon dass di1 bei jedem neuen Schleifendurchlauf neu initialisiert wird?

di1 wird aus meiner Sicht falsch gesetzt

Wie sollte es denn gesetzt werden, bzw was erwartest du? Ich habe deine Problemstellung nämlich auch nicht so ganz verstanden.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

F
Fridoo Themenstarter:in
47 Beiträge seit 2010
vor 13 Jahren

schau den 'edit' an...

1.552 Beiträge seit 2010
vor 13 Jahren

di1 ist die lauf variable die einen Wert zugewiesen bekommt der in der Liste nicht existiert.

Das kann nicht möglich sein. Mit der foreach gehst du die Liste durch, in deinem Moment das Array. Jedes Element das die foreach als aktuelles Element ausgibt, ist in der Liste vorhanden.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

F
Fridoo Themenstarter:in
47 Beiträge seit 2010
vor 13 Jahren

schaue das angehängte Bild an

dirs ist die Liste
di1 der durch die foreach Schlaufe gesetzte Wert

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo Fridoo,

leider sagt Dein Bild nicht wirklich viel aus, solange Du nicht dazuschreibst, an welcher Stelle Du genau mit dem Debugger stehst und wieviele Durchläufe u schon durch hast.

Denn innerhalb der foreach biegst Du ja dirs um mittels

            cd = di1;
            dirs = cd.GetDirectories();

Danach ist entspricht dirs nicht mehr der Collection, die im Schleifenkopf durchlaufen wird.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

F
Fridoo Themenstarter:in
47 Beiträge seit 2010
vor 13 Jahren

ich erstelle schnell ein Beispiel Projekt und werde es anhängen...

309 Beiträge seit 2008
vor 13 Jahren

Was MarsStein geschrieben hat stimmt schon:
Du fummelst in der foreach Schleife an dem Array rum das du durchläufst, das muss schief gehen.

Ich glaube du möchtest alle Unterverzeichnisse durchlaufen, richtig?

Dann schau mal hier:
Gewusst wie: Durchlaufen einer Verzeichnisstruktur (C#-Programmierhandbuch)

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo Scavanger,

Du fummelst in der foreach Schleife an dem Array rum das du durchläufst

Eigentlich nicht. Nur wird dirs eben komplett neu zugewiesen, und während im Schleifenkopf die alte Collection durchlaufen wird, auf die dirs anfänglich verwiesen hat, wird eben im Debugger die neu gesetzte dirs-Collection angezeigt.
Funktionieren kann das schon, aber die Anzeige im Debugger kann dann eben etwas verwirrend sein.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

309 Beiträge seit 2008
vor 13 Jahren

Hallo,

stimmt natürlich, aber an den (Lauf-)Variablen einer Schleife "herumzupfriemeln" halte ich für schlechten Stil. Meistens kommt eben nicht das heraus was eigentlich gemeint war.

Der Link den ich gepostet habe löst das Problem elegant per rekursivem Funktionsaufruf, wahrscheinlich hatte Threadersteller ähnliches im Sinn, so wie ich den Code verstanden habe oder besser was ich vermute was das Ziel des Codes sein soll... 🤔

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}

F
Fridoo Themenstarter:in
47 Beiträge seit 2010
vor 13 Jahren

Nur wird dirs eben komplett neu zugewiesen, und während im Schleifenkopf die alte Collection durchlaufen wird, auf die dirs anfänglich verwiesen hat, wird eben im Debugger die neu gesetzte dirs-Collection angezeigt.

Dies war mein Problem.

Ich habe jetzt einfach eine for Schlaufe verwendet anstatt eine foreach Schlaufe.
So funktioniert es:


foreach (DriveInfo drive in DriveInfo.GetDrives())
{
	Hashtable fort = new Hashtable();
	DirectoryInfo diri = drive.RootDirectory;

	int tabCount = 1;

	Console.WriteLine(diri.Name);
	while (true)
	{
		if (!fort.Contains(diri.FullName)) fort.Add(diri.FullName, diri.GetDirectories());
		for (int i = 0; i < ((DirectoryInfo[])fort[diri.FullName]).Length; i++)
		{
			Console.WriteLine(getTabs(tabCount) + ((DirectoryInfo[])fort[diri.FullName])[i].Name + "\\");

			if (((DirectoryInfo[])fort[diri.FullName]).Length == 0) break;
			DirectoryInfo mayNextDirI = ((DirectoryInfo[])fort[diri.FullName])[i];
			DirectoryInfo[] tmp = new DirectoryInfo[((DirectoryInfo[])fort[diri.FullName]).Length - 1];
			for (int c = 0; c < tmp.Length; c++)
			{
				tmp[c] = ((DirectoryInfo[])fort[diri.FullName])[c + 1];
			}
			fort[diri.FullName] = tmp;

			if (mayNextDirI != null)
			{
				try
				{
					diri = mayNextDirI;
					fort.Add(diri.FullName, diri.GetDirectories());
					tabCount++;
				}
				catch (UnauthorizedAccessException e)
				{
					diri = diri.Parent;
					Console.WriteLine(getTabs(tabCount + 1) + e.Message);
				}
			}
			i = -1;
		}
		for (int i = 0; i < diri.GetFiles().Length; i++)
		{
			Console.WriteLine(getTabs(tabCount) + diri.GetFiles()[i].Name);
		}
		if (diri.Parent == null) break;
		diri = diri.Parent;
		tabCount--;
	}
}

U
1.578 Beiträge seit 2009
vor 13 Jahren

Es heißt Schleife und nicht Schlaufe