(object)casting ... vs (object[]) casting... was ist der Unterschied?



  • Danke Leute für Eure Tips. Ich muss jetzt erstmal weg für paar Stunden, aber ich werd mir das später mal genauer anschauen. Ich bin ja noch ziemlicher cpp-newbie 🙂 deshalb immer dankbar für Hinweise. 🙂
    cu



  • TobiBob schrieb:

    Ich bin ja noch ziemlicher cpp-newbie

    *C# newbie :p



  • 314159265358979 schrieb:

    TobiBob schrieb:

    Ich bin ja noch ziemlicher cpp-newbie

    *C# newbie :p

    :p ... wollte nicht extra dafür den post editieren 😃

    FreakY<3Cpp schrieb:

    obj = line.Split(new char[1] { '\x01' }, 15).ToArray<object>();
    

    So bleibt dein object-Array weiterhin ein Array vom Typ object.

    Bist du dir da sicher? Ich habe das jetzt gerade ausprobiert, wäre ne sehr elegante Lösung, funktioniert aber nicht. Es bleiben Strings... Kann vielleicht Split().ToArray<>() in der Vererbungshierarchie nicht nach oben gehen?

    Und

    obj = line.Split(new char[1] { '\x01' }, 15).Cast<object>();
    

    wollte ich mal testen - lässt sich nicht compilieren.

    @Rhombicosidodecahedron, danke, geht auch gut, kann ich bestimmt an anderer Stelle benutzen.



  • Folgendes Beispiel funktioniert:

    object[] obj = new object[15];
    string line = "hallo und so";
    
    obj = line.Split(new char[1] { ' ' }).ToArray<object>();
    obj[0] = "string";
    obj[1] = 5;
    

    Ich habe versucht es so sehr wie möglich wie deins aussehen zu lassen und wie gesagt, es funktioniert.



  • FreakY<3Cpp schrieb:

    Ich habe versucht es so sehr wie möglich wie deins aussehen zu lassen und wie gesagt, es funktioniert.

    :)Ja, aber ich möchte ja etwas in dieser Richtung machen:

    object[] obj = new object[15];
    string line = "1 und 1,5";
    
    obj = line.Split(new char[1] { ' ' }).ToArray<object>();
    obj[0] = (int)obj[0];     // Laufzeitfehler: angegebene Umwandlung ungültig
    obj[2] = (double)obj[2];  // Laufzeitfehler         "
    

    Wenn ich mir im Debuggingfenster obj[0].GetType() anzeigen lasse, ist das ein string. Ich will ja keine neue Referenz anlegen, sondern nur das vorhandene typecasten. ... also wenn ich mit nur 1 Array arbeite.

    Eigentlich sollte ich für die DataTable-Columns auch die Typen definieren. Dann geschieht bestimmt irgendne expliziete Umwandlung im Hintergrund. Ich bin jetzt aber noch nicht so weit vorgedrungen.



  • object[] obj = new object[15];
    
    obj = line.Split(new char[1] { ' ' }).ToArray<object>();
    

    Die erste Zeile ist sinnlos weil in der zweiten Zeile ein neues Array angelegt wird (String array um genau zu sein) und das vorherige Array ersetzt. Das object[15] array ist damit nicht mehr referenziert und kann von der GC abgeräumt werden.

    Genauso gut könnte man schreiben:

    object[] obj = line.Split(new char[1] { ' ' }).ToArray<object>();
    

    Wobei Split ein String-Array liefert und kein Object-Array.



  • TobiBob schrieb:

    obj[0] = (int)obj[0];     // Laufzeitfehler: angegebene Umwandlung ungültig
    obj[2] = (double)obj[2];  // Laufzeitfehler         "
    

    Sowas wie (int)"23" geht nicht. Du musst schon int.Parse() und double.Parse() verwenden.



  • @loks, Ok, leuchtet ein. Aber das wird ja für jede Zeile aus der Datei gemacht, und ich will nicht für jede Zeile eine neue object[] -Instanz anlegen.

    Aber dann kann ich z.b. oben auch nur schreiben

    object[] obj = null;
    

    @µ, ja ist klar, aber dann scheints komme ich doch nicht darum herum, 2 arrays zu benutzen. Oder kann ich das string.Split() direkt in ein DataRow-Objekt umwandeln oder einem zuweisen, wenn die columns andere Typen haben? Dann müsste ich vielleicht nochmal ein IFormatProvider-Array definieren, aber das wird dann nur umständlicher.

    Edit:
    Aber eine andere Frage geht mir die ganze Zeit durch den Kopf: Muss ich die Daten eigentlich als chars abspeichern? Gibts nicht ne FileStream-Möglichkeit, die reinen Daten zu speichern, ohne sie in chars vorher zu konvertieren? Dann würden beim Einlesen auch die ganzen Konvertierungen wegfallen können.



  • Was spricht gegen

    obj = line.Split(new char[1] { ' ' }).ToArray<object>();
    obj[0] = int.Parse(obj[0]);
    obj[2] = double.Parse(obj[2]);
    

    Wobei ich wahrscheinlich TryParse bevorzugen würde, da du wie es aussieht, Daten aus einer Datei ausließt und du, solange du dir nicht wirklich sicher bist, dass da auch jemand anderes dran rumfuchteln könnte, somit eine FormatException bekommen könntest.



  • @FreakY<3Cpp, *grübel* irgendwas muss ich vorher falsch gemacht haben. Jetzt gehts auch bei mir 🙄 ... Danke jedenfalls.

    Und hinsichtlich TryParse: Habe ich auch überlege. Das ganze ist natürlich in einem try{}catch{} -Block, aber wenn jemand, bzw. mein Kollege, der das beruflich braucht, in den Rohdateien rumfuscht, stimmt die ganze Auswertung nicht mehr. Da bringts dann auch nichts, wenn nur 1 Wert durch TryParse auf 0, statt auf dem originalen ist, sondern es ist besser, wenn ne anständige Fehlermeldung kommt. Vielleicht kann man die Dateien programmatisch auch mit einem schreibschutz versehen, oder ich lasse automatisch backups generieren.
    So jedenfalls die Überlegung, aber das ist bestimmt auch diskussionswürdig. 🙂



  • Sein Problem ist nicht nur das er sicher sein muss das das Konvertieren Klappt, sondern auch die Feste Vorgabe das es 15 Elemente sein sollen.
    Generell würde ich nicht mit Arrays arbeiten.

    Ich würde es in etwa so lösen (in 5-10 Minuten mal eben runter geklöppelt):

    class Program
    {
    	static void Main(string[] args)
    	{
    		object[] items = Split("This 11 is an stupid 7 example");
    		foreach (var item in items)
    		{
    			Console.WriteLine("{0} : {1}", item, item.GetType());
    		}
    	}
    
    	private static object[] Split(string line)
    	{
    		var items = new List<object>();
    		foreach (var part in line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
    			items.Add(ToConcrete(part));
    		return items.ToArray();
    	}
    
    	private static object ToConcrete(string part)
    	{
    		if (char.IsNumber(part, 0)) // Very stupid; it checks just the first character
    			return AsInteger(part, 0);
    		return part;
    	}
    
    	private static object AsInteger(string number, int fallback)
    	{
    		int converted = fallback;
    		if (int.TryParse(number, out converted))
    			return converted;
    		return fallback;
    	}
    }
    

    Ausgabe:

    This : System.String
    11 : System.Int32
    is : System.String
    an : System.String
    stupid : System.String
    7 : System.Int32
    example : System.String
    

    Das erkennen des Types müsste man noch intelligenter machen.

    Dann gibt man kein Array fester Größe vor und konvertiert nur bei Bedarf.


Anmelden zum Antworten