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

  • »
  • Community
  • |
  • Diskussionsforum
Operator checked / checked Anweisungsblock
RafaelVogt
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

Operator checked / checked Anweisungsblock

beantworten | zitieren | melden

Hallo zusammen, dies ist die 2te Frage im Zusammenhang mit meinem Wunsch C# von grundauf zu lernen. Mittlerweile bin ich am Ende des Kapitels "Variablen und Datentypen" angekommen. Hier geht es um den Operator >>checked<<. Ich weiß, das er einen Laufzeitabbruch verursacht und vor einem "Überlauf" schützt. Hier mein bisheriges Wissen:


namespace _04_elementare_Datentypen
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Die Operatoren >>checked<< und >>unchecked<<:");
            
            Console.WriteLine("Geben Sie eine Zahl im Bereich von ");
            Console.WriteLine($"0...{Int16.MaxValue} ein:");
            
            short value20 = Convert.ToInt16(Console.ReadLine());
            
            byte value21 = checked((byte)value20);
           
            Console.WriteLine(value21);

            Console.ReadKey();
        }
    }
}

Bis hier her komme ich mit. Gibt man z.B. einn Wert 256 ein, würde das zu einem Überlauf führen und der >>checked<< Operator bricht die Laufzeit ab. Nun steht in dem Buch einfach folgender Satz.
Zitat
"Falls nich nur ein einzelner Ausdruck, sondern mehrere Ausdrücke innerhalb eines Anweisungsblocks auf einen möglichen Überlauf hin kontrolliert werden, können sie hinter >>checked<< einen Anweisungsblock angeben. Folgendes Beispiel dazu wird dann im Buch geliefert.


namespace _04_elementare_Datentypen_8
{
    class Program
    {
        static void Main(string[] args)
        {
            checked
            {
                short shortValue = 436;
                int integerValue = 1236555;
                byte byteValue = (byte)shtVar;
                shortValue = (short)integerValue;
                Console.WriteLine(byteValue);
                Console.ReadLine();
            }
        }
    }
}

Erstens verstehe ich nicht wie ich diesen Anweisungsblock in zum Beispiel den obigen Code einfügen soll, und zweitens ist die Variable


shtVar

gar nicht definiert. Was also versucht man mir hier zu sagen?

Vielen Dank im Voraus.
private Nachricht | Beiträge des Benutzers
OlafSt
myCSharp.de - Member



Dabei seit:
Beiträge: 78
Herkunft: HH

beantworten | zitieren | melden

Das ist doch total simpel

Dein Code müsste, würde er den checked-operator konsequent nutzen, so aussehen:


short value20 = checked(Convert.ToInt16(Console.ReadLine()));
byte value21 = checked((byte)value20);

Wenn das jetzt nicht nur 2 Zeilen sind, sondern 132 Zeilen mit solchem Code, wird es echt mühsam, immer wieder checked() einzutippen. Also machen wir n Block draus:


checked
{
     short value20 = Convert.ToInt16(Console.ReadLine());
     byte value21 = (byte)value20;
}

Alle checked-operatoren sind nun weg, nur der eine um den Block herum ist noch da. Aber der umfasst eben ALLE Zeilen im Block. That simple

Die fehlende Variable im Buch ist ein Fehler des Lektorats. Lektoren können toll Rechtschreibung und Grammatik, aber nicht programmieren. Die wissen nicht, das shtVar auch mit shortValue ersetzt werden muss, wie es der Autor vorher getan hat
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von OlafSt am .
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.820
Herkunft: Waidring

beantworten | zitieren | melden

Hallo RafaelVogt,

anstatt der checked Blöcke kann das auch "global" eingestellt werden.
Projekteigenschaften -> Build -> Advanced -> Checkbox "Check for arithmetic overflow/underflow"
Wobei ich jedoch die expliziten checked Blöcke und Anweisungen bevorzugen, da es eben sofort ersichtlich ist worum es geht.

Siehe zum Thema auch CA2233: Operations should not overflow

Da du gerade beim Lernen bist, noch ein Hinweis:
Zitat


short value20 = Convert.ToInt16(Console.ReadLine());
erzeugt einen Laufzeitfehler, falls Console.ReadLine keine Zahl (in Text-Form) liefert. Wenn du z.B. "abc" eingegeben hast anstatt einer erwarteten Zahl, so stürzt das Programm ab.
Abhilfe schafft entweder den Fehler mittels try catch zu fangen und behandeln od. noch besser


if (short.TryParse(Console.ReadLine(), out short value20))
{
    // Zahl konnte erfolgreich geparst werden
}
else
{
    // Zahl konnte nicht geparst werden
}
zu verwenden. Ob und wie auf das "nicht parsen" reagiert wird, hängt von der Anwendung ab.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
RafaelVogt
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Zitat von OlafSt
Dein Code müsste, würde er den checked-operator konsequent nutzen, so aussehen:


short value20 = checked(Convert.ToInt16(Console.ReadLine()));
byte value21 = checked((byte)value20);

Mit ...


short value20 = checked(Convert.ToInt16(Console.ReadLine()));

... machst du genau was?

Sorry... es ist echt verwirrend.
private Nachricht | Beiträge des Benutzers
RafaelVogt
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Ach um gleich zu checken ob der eingegebene Wert nicht den short überläuft?
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.820
Herkunft: Waidring

beantworten | zitieren | melden

Hallo RafaelVogt,
Zitat von RafaelVogt
Zitat von OlafSt
Das ist doch total simpel :D
Mit ...


short value20 = checked(Convert.ToInt16(Console.ReadLine()));

... machst du genau was?

Sorry... es ist echt verwirrend.

Hier macht das checked nicht viel Sinn, da Int16 der Typ des Schlüsselworts short ist. Da kannst du es weglassen.

Anders wäre es z.B. bei


short s0 = checked(Convert.ToUInt16(Console.ReadLine()));
da bei der Konvertierung* ein ushort zurückgegeben wird, das könnte bei der Zuweisung zu short überlaufen.
Od. beim Beispiel von oben mit der Zuweisung zu byte.

Generell ist auf (arithmetischem) Über-/Unterlauf zu achten, wenn verschiedene Wertebereiche im Spiel sind. Entweder wird explizit im Code geprüft ob es passt (z.B. per if) od. mit checked od. gar nicht, falls Überlauf akzeptabel ist.

* bitte unbedingt meinen obigen Hinweis zu den TryParse-Methoden beachten.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
RafaelVogt
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Vielen, vielen Dank.
private Nachricht | Beiträge des Benutzers