Hallo.
Ich komme im Moment nicht weiter.
Ich möchte "Strings.Join" nutzen ...
Strings.Join(object[], string)
jetzt habe ich aber folgendes:
List<UInt32> Code ...
...
object[] Test = (object[]) Code.ToArray(); // Zum Testen, aber hier hängt es schon :-(
...
String NeuesLiteral = Strings.Join(Test, ";");
...
Ich komme nicht dahinter, wie ich den Cast machen kann, um aus meiner List<UInt32> (bzw. UInt32[]) ein object[] für die Strings.Join(object[], string)-Methode zu bekommen ...
mfg Hajoseb
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France
Hallo Hajoseb,
object [] aobj = new object [Code.Count];
Code.ToArray ().CopyTo (aobj, 0);
oder
Array.ConvertAll
herbivore
List<T> bietet eine CopyTo-Funktion.
Casts von object[] nach string[] sind nicht möglich. Genauso nicht UInt32[] nach String[]. Soweit ich mich erinnern kann implementiert der C#-Compiler bei Arrays allerdings implizite Konvertierungen für implementierte Schnittstellen an. Ein Control[]-Array kannst du beispielsweise zu einem IDisposable[]-Array konvertieren.
Alles andere musst du mit einer Schleife selbst gestalten.
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
Hallo kleines_eichhoernchen,
- List<T> bietet eine CopyTo-Funktion.
die allerdings typisiert ist, d.h. man kann kein Object[] als Ziel angeben.
- Casts von object[] nach string[] sind nicht möglich. Genauso nicht UInt32[] nach String[].
Darum geht es Hajoseb ja gar nicht. Er verwendet Strings.Join und nicht String.Join und braucht daher ein Object[] und kein String[].
herbivore
Ja gut, dann hatte ichs falsch verstanden.
Bei
Code.ToArray().CopyTo (aobj, 0);
würde ich es dennoch vorziehen, eine einfache Schleife zu verwenden. Spart man sich eine komplette Array-Konvertierung
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
...
würde ich es dennoch vorziehen, eine einfache Schleife zu verwenden. Spart man sich eine komplette Array-Konvertierung
Das ist es ja gerade ... letztens hatte mir herbivore gerade Strings.Join empfohlen, aber ich hatte es nicht geschafft, diese Methode auch zu nutzen ...
object [] aobj = new object [Code.Count]; Code.ToArray ().CopyTo (aobj, 0);
oder
Array.ConvertAll
Bringt mir dann das ganze überhaupt noch einen Vorteil gegenüber einer "normalen" schleife mit "String += ..." oder "StringBuilder.Append" ???
mfg Hajoseb
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France
Hallo Hajoseb,
wenn du auf einfachem Wege die String-Repräsentationen der einzelnen Elemente beliebiger Collections zu einem Strings zusammenfügen willst, ist es in der Tat etwas umständlich, diese erst in ein Objekt-Array umwandeln zu müssen. Aber du kannst das ja in einer eigenen Methode kapseln:
using System;
using System.Text;
using System.Collections.Generic;
using IUntypedEnumerable = System.Collections.IEnumerable;
using IUntypedEnumerator = System.Collections.IEnumerator;
static class App
{
public static void Main (string [] astrArg)
{
List <int> list = new List <int> ();
list.Add (1);
list.Add (2);
list.Add (3);
Console.WriteLine (StringJoin (list, ", "));
}
public static String StringJoin (IUntypedEnumerable coll, String strDelim)
{
StringBuilder sbResult = new StringBuilder ();
IUntypedEnumerator enumerator = coll.GetEnumerator ();
try {
if (!enumerator.MoveNext ()) { return ""; }
sbResult.Append (enumerator.Current);
while (enumerator.MoveNext ()) {
sbResult.Append (strDelim);
sbResult.Append (enumerator.Current);
}
}
finally {
IDisposable disposable = enumerator as IDisposable;
if (disposable != null) { disposable.Dispose (); }
}
return sbResult.ToString ();
}
}
herbivore
Hallo, herbivore. Danke 👍
Mein Ansatz gestern war dieser:
private static String Code2String(List<UInt32> Code, String Trennzeichen)
{
StringBuilder NeuesLiteral = new StringBuilder();
foreach (var Spalte in Code)
{
NeuesLiteral.Append(Spalte.ToString() + Trennzeichen); // Kann man auch mit 2 Append machen und ohne .ToString() ...
}
return NeuesLiteral.ToString().TrimEnd(Trennzeichen);
}
Spricht etwas dagegen, dies ohne IUntypedEnumerable in IUntypedEnumerator zu machen, oder hat meine "kurze" Schreibweise einen gravierenden Nachteil, den ich als Einäugiger unter den Blinden (= Anfänger) nicht sehe?
mfg Hajoseb
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France
Hallo Hajoseb,
ja, deine Lösung funktioniert nur List<UInt32> und wenn du sie generisch für beliebige List<T> machst, kann es bei Spalte.ToString() knallen. Aber selbst bei einer Erweiterung auf List<T> kannst du keine Arrays und anderen Collections übergeben. Das ist bei mir gerade durch IUntypedEnumerable möglich. Außerdem würde bei einer Erweiterung deines Code auf beliebige Typen, das Entfernen des Trenners nicht wirklich funktionieren. Es funktioniert schon jetzt bei dir nicht zuverlässig, wenn man als Trenner eine Ziffer(nfolge) verwendet. TrimEnd macht etwas anders als du wohl vermutest. Wenn du den überflüssigen Trenner am Ende entfernen willst und nicht wie ich vermeidest, dass er überhaupt dazugefügt wird, dann solltest du das mit String.Substring oder String.Remove machen.
herbivore
Oha. Ja. Kapiert.
Ich habe zu lokal (kurz) gedacht und nicht, wie du, global 👍
Auf die Idee, eine allgemein gültige Lösung zu suchen, bin ich gar nicht erst gekommen 🤔
Man lernt halt nie aus ...
mfg Hajoseb
P.S. In meinem original-Code habe ich den Trenner sogar fest auf ";" für .csv-Dateien gesetzt gehabt 🙂. Habe das andere nur in der gepsoteten Variante auf "string Trenner" erweitert ... War also noch "lokaler" auf mein Problem bezogen ...
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France
Hallo Hajoseb,
mein Code ist ja auch nur deshalb so "aufgebläht", weil ich die foreach-Schleife manuell in eine while-Schleife umgesetzt habe, was sonst der Compiler tut, um nicht im Schleifenrumpf immer fragen zu müssen, ob ich beim ersten Element bin. Mein Code stellt ja im Prinzip nichts anders dar als eine foreach-Schleife, bei der das erste Element anders behandelt wird.
Schön wäre, wenn das C# direkt unterstützen würde, also sowas wie:
foreach (...) {
first:
// statments
last:
// statments
others:
// statments
}
Und das der Compiler nicht per if-Abfrage im Schleifenrumpf realisieren würde, sondern automatisch so in Code umsetzen würde, wie ich das manuell gemacht habe.
herbivore
Sende doch den Vorschlag malan Microsoft. Die wollen doch immer Vorschläge aus dem "Feld" 😉 und dein Wort als angesehener Forumsleiter zählt doch dann sicher etwas 8)
mfg Hajoseb
btw: Stelle dein StringJoin doch mal bei den Snippets rein. Ist doch sicher für andere auch eine gute Lösung 👍
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France
Hallo herbivore,
Schön wäre, wenn das C# direkt unterstützen würde, also sowas wie:
foreach (...) { first: // statments last: // statments others: // statments }
Und das der Compiler nicht per if-Abfrage im Schleifenrumpf realisieren würde, sondern automatisch so in Code umsetzen würde, wie ich das manuell gemacht habe.
Das wäre wirklich super. Mir geht es oft so, dass ich anstatt einer foreach
- dann die "normale" for
-Schleife verwende, weil genau das nicht funktioniert ...
Ohne mich jetzt groß im Compilerbau auszukennen, behaupte ich, dass das keine schwierige Sache ist ...
m0rius
Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg
Kann man eigentlich statt
finally {
IDisposable disposable = enumerator as IDisposable;
if (disposable != null) { disposable.Dispose (); }
}
Nicht auch ein
using (IUntypedEnumerator enumerator = coll.GetEnumerator ())
{
...
}
nutzen ???
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France
Hallo Hajoseb,
das führt jetzt spätestens ziemlich vom Thema weg. Deshalb nur kurz und knapp: Nein, denn für using ist zwingend erforderlich, dass die benutze Klasse IDisposable implementiert oder zumindest deren Objekte implizit dahin konvertiert werden kann. Das ist bei Klassen, die IUntypedEnumerator implementieren, aber gerade nicht zwangsweise so.
herbivore