Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

[erledigt] Konvertierung - Unterschied Convert.ToByte(i) und (byte)i
CoLo
myCSharp.de - Member



Dabei seit:
Beiträge: 224

Themenstarter:

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

beantworten | zitieren | melden

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?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von CoLo am .
private Nachricht | Beiträge des Benutzers
7.e.Q
myCSharp.de - Member

Avatar #avatar-3402.jpg


Dabei seit:
Beiträge: 925
Herkunft: Scheeßel

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
pdelvo
myCSharp.de - Member

Avatar #avatar-3354.png


Dabei seit:
Beiträge: 1.346

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
chriscolm
myCSharp.de - Member



Dabei seit:
Beiträge: 112

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 5.742
Herkunft: Stuttgart

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
CoLo
myCSharp.de - Member



Dabei seit:
Beiträge: 224

Themenstarter:

beantworten | zitieren | melden

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 =)
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.649
Herkunft: Leipzig

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
CoLo
myCSharp.de - Member



Dabei seit:
Beiträge: 224

Themenstarter:

beantworten | zitieren | melden

Okay, okay, okay, okay ... überredet ... =)
private Nachricht | Beiträge des Benutzers