Laden...

[erledigt] Konvertierung - Unterschied Convert.ToByte(i) und (byte)i

Erstellt von CoLo vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.926 Views
C
CoLo Themenstarter:in
224 Beiträge seit 2009
vor 11 Jahren
[erledigt] Konvertierung - Unterschied Convert.ToByte(i) und (byte)i

Hi Leute, habe eine Grundlagenfrage.

Gibt es einen Unterschied zwischen nachfolgenden Konvertierungen
und was muss man bedenken?:


  int i;
  byte b;
  //(...)
   b = Convert.ToByte(i);
   checked { b = (byte)i; }

Ich habe das mal mit

 Int16 i;

grob ausprobiert für einige Zahlen aus 32767 bis -32768. Scheint alles gleich. (Ein vollständiger Test dauert Ewigkeiten.)

Ich verwende gerne

b = (byte)i;

und bin mir bewusst, dass beim Überlauf der Teil beim Überlauf abgeschnitten wird. Den Umstand nutze ich auch gerne aus.

Nun lese ich, dass einige in den Compileroptionen die Überlaufsprüfungen einschalten, so dass aus

b = (byte)i;

automatisch

   checked { b = (byte)i; }

wird. Alles hat ja seinen Grund. Wie macht Ihr das bzw. was haltet Ihr davon?

925 Beiträge seit 2004
vor 11 Jahren

Ohne die Frage jetzt direkt beantworten zu können; du kannst ja mal einen Benchmark damit probieren, also die Zeit stoppen, die für Convert und für einen normalen Cast gebraucht wird.

Darüber hinaus könntest du dir anschauen, was der Compiler aus den beiden Aufrufen macht. Wenn er gut optimiert, dürften beide Aufrufe den gleichen Maschinencode ergeben.

Wissen tu ich das allerdings nicht. 🤔

1.346 Beiträge seit 2008
vor 11 Jahren

Was sich immer wieder lohnt ist ein Block in einen Disassembler.

Convert.ToByte(char) prüft, ob das char ausserhalb des erlaubten Bereiches (> '\x00ff') ist, und wirft eine OverflowException, falls das der Fall ist. Wenn nicht wird dort auch gecastet: (Byte)value

LG pdelvo

C
112 Beiträge seit 2009
vor 11 Jahren

Moinsen,

ich bevorzuge in geeigneten Fällen Convert.To...
Wenn das Argument aus irgendwelchen Gründen null ist oder sonstwie nicht passt, gibt Convert.To... den Default-Value des Typs zurück.

object o = null;
int i = (int)o; // -> wummmss!!!
int i = Convert.ToInt32(o); // -> i = 0;

Grüße

Christian

5.742 Beiträge seit 2007
vor 11 Jahren

Hallo CoLo,

ich persönlich handhabe das ganze wie folgt:

Wenn ich es nicht mal vergesse, schalte ich in den Buildoptionen meiner Projekte immer die Option "Check for arithmetic over-/underflow" (unter "Build-Advanced" unter VS). Diese hat quasi den gleichen Effekt wie ein "großer" checked-Block um den gesamten Code.

Hintergrund ist, dass man IMHO beim "normalen" Lesen von Code nicht über eventuelle Overflows nachdenkt. Bei der Ausführung des Codes wird somit sichergestellt, dass dieser keine "unangenehmen" Überraschungen enthält; ich kann davon ausgehen, dass kein Bug, der durch unabsichtlichen Overflow verursacht wird, unentdeckt bleibt.

Will ich hingegen bewusst Overflows ausnutzen, sodass "(sbyte) 255" auch tatsächlich "-1" ergibt, verwende ich für diese Stellen unchecked. Erfahrunsgemäß beschränkt sich dies auf wenige Klassen bzw. Methoden (die dann Algorithmen auf Bytebene implementieren).

Die Convert Klasse verwende ich recht selten; hauptsächlich, wenn ich wie im Beispiel von chriscolm von Object aus casten will, und nicht genau weiß, ob sich jetzt hinter dem Objekt ein Integer, ein Byte oder doch etwas anderes verbirgt.
Convert.ToXXX nutzt ja soweit ich mich erinnern kann auch IConvertible<T>, was die normalen Casts nicht tun.

C
CoLo Themenstarter:in
224 Beiträge seit 2009
vor 11 Jahren

Vielen dank für die Antworten.
Ich glaube ich werde in Zukunft mehr mit checked arbeiten. Auf jeden Fall mehr darüber Nachdenken. Vielleicht werde ich später mal die Überlaufsprüfung in den Compileroptionen einschalten.

Gruß, CoLo =)

5.657 Beiträge seit 2006
vor 11 Jahren

Hi CoLo,

ich glaube, der Hinweis von winSharp93 war genau andersherum gemeint. Die Überlaufprüfung in den Build-Optionen sollte immer angeschaltet sein, denn damit bekommst du Hinweise auf fehlerhaften Code. In den allermeisten Fällen ist ein Überlauf nämlich nicht erwünscht. Nur in den wenigen Fällen wie bei der Hashcode-Berechnung solltest du dann unchecked-Blöcke verwenden, um explizit die Überlaufprüfung auszuschalten.

Christian

Weeks of programming can save you hours of planning

C
CoLo Themenstarter:in
224 Beiträge seit 2009
vor 11 Jahren

Okay, okay, okay, okay ... überredet ... =)