foreach mit Index (Laufvariable)
-
volkard schrieb:
Tja. Du bist halt eine Flasche, sagen manche Anfänger.
Hast Du irgendein persönliches Problem mit mir?
-
µ schrieb:
volkard schrieb:
Tja. Du bist halt eine Flasche, sagen manche Anfänger.
Hast Du irgendein persönliches Problem mit mir?
Nein, DU bist für mich ein Profi im nichteigenlichen (im eigentlichen vielleicht auch, das kann ich aber kaum wissen) Sinne. Du bist mir sehr oft mit einer Expertise positiv aufgefallen.
-
Dravere schrieb:
David W schrieb:
Im übrigen, "Sequenz kopieren"? Wenn du eine IEnumerable hast daraus eine Liste machst werden auch nur die Referenzen geholt und gesammelt in einer Liste angeboten. Die Leistung dürfte zu vernachlässigen sein, außer eventuell das alle Referenzen direkt aufgelöst werden.
Mit solchen Aussagen wäre ich vorsichtig. Vor allem wenn es um allgemeine Aussagen geht. Man sollte nie vergessen, dass es auch Linq to SQL gibt. Ein
IEnumerable
könnte plötzlich Abfragen in einer Datenbank machen. DasToList
führt dann alle Abfragen durch, womöglich ungewollt.Grüssli
Aber wenn ich eh mit foreach eine Iteration über die gesamte Menge laufen lasse, spielt das dann aber auch keine Rolle mehr. Außer das ein paar Referenzen kopierte werden, wie David oben angemerkt hat. Wenn man in seiner foreach Schleife eine Abbruchbedingung drinnen hat, dann ist mir schon klar, das ToList nicht immer elegant ist
-
µ schrieb:
EDIT: Jetzt komme ich auch ins Schleudern. Wurde Count() für z.B. List überschrieben?
Geht das überhaupt? Wird für Extension Methods ein Dispatch gemacht?
µ schrieb:
Es gibt noch zwei Sonderfälle einer Iteration: Das erste und das letzte Element müssen häufig gesondert von den restlichen Elementen einer Enumeration behandelt werden.
Ich habs glaub ich schonmal gesagt: Die eigentliche Warze ist foreach. Ein Statement, das genau dann elegante Lösungen ermöglicht, wenn man genau das machen will, was sich der Designer gedacht hat. Kleine Abweichungen: Pech gehabt!
(Vielleicht ist es auch meine Lisp-Vergangenheit. Lernt bloß nie Lisp, dann ist alles frustrierend.)
-
Es gibt eine Sprache die innerhalb von foreach automatisch eine Variable namens $ zur Verfügung stellt die als Laufvariable dient. Das ist wunderschön *mir für C# wünsch* *auch wenn mich Bashar knüppelt*
MfG SideWinder
-
Bashar schrieb:
µ schrieb:
EDIT: Jetzt komme ich auch ins Schleudern. Wurde Count() für z.B. List überschrieben?
Geht das überhaupt? Wird für Extension Methods ein Dispatch gemacht?
Sieht nicht so aus, aber es gibt offenbar Wege: http://www.codeproject.com/KB/tips/PolymorphExtensionVisitor.aspx
*volkards Posting nicht ganz versteh, mir jemand erklären will?*
MfG SideWinder
-
Noob3453 schrieb:
Aber wenn ich eh mit foreach eine Iteration über die gesamte Menge laufen lasse, spielt das dann aber auch keine Rolle mehr. Außer das ein paar Referenzen kopierte werden, wie David oben angemerkt hat. Wenn man in seiner foreach Schleife eine Abbruchbedingung drinnen hat, dann ist mir schon klar, das ToList nicht immer elegant ist
Nicht nur wegen der Abbruchbedingung. Es können auch Nebeneffekte erst in der Schleife auftreten, welche das Ergebnis verändern würden. Wie gesagt, einfach mit Vorsicht behandeln.
@μ,
Empfinde ich seltsam, dass du immer wieder einen Index brauchst. Deshalb habe ich nämlich nachgefragt. Bei der Antwort von Bashar auf meine Frage, sieht man, dass er es eher in Ausnahmefällen benötigt. Bei dir scheint das ja eher ganz normal zu sein.
Ich frage mich daher, ob du nicht irgendetwas falsch machst? Vielleicht solltest du deine Design etwas überdenken? Wieso genau brauchst du immer wieder einen Index? Könnte man es anders lösen? Den Index als ID zu nehmen, halte ich übrigens für extrem gefährlich. Sowas sollte man nur temporär machen. Aber wieso überhaupt? Du hast ja sowieso nur einIEnumerable
, wieso brauchst du dann eine ID? Was wäre die Alternative zu dieser ID? usw.@all,
LinqCount
verwendetICollection<T>.Count
, sofern dies zur Verfügung steht:
http://msdn.microsoft.com/en-us/library/bb338038.aspxMSDN schrieb:
Remarks
If the type of source implementsICollection<T>
, that implementation is used to obtain the count of elements. Otherwise, this method determines the count.Grüssli
-
Der Index wird eigentlich total selten gebraucht, und dort wo es gebraucht wird kann man ja mal schauen ob eine ToList() nicht tatsächlich schon reichen würde ("mit vorsicht behandeln").
Es wird praktisch nie vorkommen das man ein index braucht und nicht mit ToList arbeiten kann wegen Seiteneffekten.
Und selbst dann kann man mit einem Index arbeiten der außerhalb der for definiert ist, wenn die Lebensdauer stört der kann ja ein leeren Scope block definieren."foreach (var pair in myList.ToIndexedEnumerable())" ist zwar sehr elegant aber nicht so lesbar, da es zum einen nicht in der MSDN steht. Das man den Namespace der Extension Method kennen muss. Wissen das es da ist, und zu guter letzt wissen das ToIndexedEnumerable eine KeyValuePair Liste zurückgibt.
Eleganz hin oder her, Code wird öfter gelesen als geschrieben, also nimmt man das einfacherer.
Ich hatte erst letztens eine Mail von den CCD Jungs und da hieß es auch:Clean Code ist gut; aber eleganter Code ist noch besser. Oder?
In einem vieldiskutierten Blogartikel argumentiere ich dagegen. Mein Plädoyer gilt transparentem Code. Was er tut und wie er es tut, soll klar erkennbar sein. Code soll geradezu nakt vor dem lesenden Entwickler stehen. Details zu verbergen, mag in anderen Bereichen eine Tugend sein; in der Softwareentwicklung ist es Unverhülltheit.
Quelle: http://ralfw.blogspot.com/2011/06/porno-statt-erotik-in-der.html
-
Dravere schrieb:
David W schrieb:
Im übrigen, "Sequenz kopieren"? Wenn du eine IEnumerable hast daraus eine Liste machst werden auch nur die Referenzen geholt und gesammelt in einer Liste angeboten. Die Leistung dürfte zu vernachlässigen sein, außer eventuell das alle Referenzen direkt aufgelöst werden.
Mit solchen Aussagen wäre ich vorsichtig. Vor allem wenn es um allgemeine Aussagen geht. Man sollte nie vergessen, dass es auch Linq to SQL gibt. Ein
IEnumerable
könnte plötzlich Abfragen in einer Datenbank machen. DasToList
führt dann alle Abfragen durch, womöglich ungewollt.Grüssli
Noch eine Frage zu deinem Beispiel mit SQL. Wenn hinter einer Enumeration eine Datenbankabfrage steht, dann geschieht dies doch über sog. Proxy-Objekte. Ein Proxy wird aber erst aufgelöst, wenn auf eines der Properties zugegriffen wird. Ein ToList() würde doch dann nur die Referenz kopieren, aber nicht den Proxy auflösen.
-
Noob3453 schrieb:
Noch eine Frage zu deinem Beispiel mit SQL. Wenn hinter einer Enumeration eine Datenbankabfrage steht, dann geschieht dies doch über sog. Proxy-Objekte. Ein Proxy wird aber erst aufgelöst, wenn auf eines der Properties zugegriffen wird. Ein ToList() würde doch dann nur die Referenz kopieren, aber nicht den Proxy auflösen.
Nein, meistens ist der Proxy das
IEnumerator
Objekt. Dann wird die Abfrage mitMoveNext
ausgelöst. Das Problem ist wirklich, was sich eigentlich hinter demIEnumerator
versteckt, den man vomIEnumerable
bekommt.Grüssli
-
private void Foo(IEnumerable<string> bar) { for (int i = 0; i < bar.Count(); ++i) { var item = bar.ElementAt(i); } }
-
David W schrieb:
private void Foo(IEnumerable<string> bar) { for (int i = 0; i < bar.Count(); ++i) { var item = bar.ElementAt(i); } }
Quadratische Laufzeit.