| Autor |
Beitrag |
Christoph1972
      
Beiträge: 690
Erhaltene Danke: 16
VS2015 Pro / C# & VB.Net
|
Verfasst: Mo 13.07.09 17:01
Hallo zusammen,
ich wunder mich gerade über den C# Compiler. Beispiel C#:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| private void button1_Click(object sender, EventArgs e) { Double a = button1.Height; Double b = button1.Width; Double test1 = a / b; Double test2 = button1.Height / button1.Width; Int32 test3 = button1.Height / button1.Width; } |
Beispiel VB.Net: (es gibt leider keine Bereiche für VB.Net)
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Option Strict = On
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim a As Double = Button1.Height Dim b As Double = Button1.Width
Dim test1 As Double = a / b 'passt
Dim test2 As Double = Button1.Height / Button1.Width 'passt
Dim test3 As Int32 = Button1.Height / Button1.Width ' hier setzt der Compiler den Rotstift an, prima
End Sub |
Kann mir mal bitte jemand erklären was hier los ist? C# ist doch Type-Sicher, das darf doch nicht sein, oder?
Gruß
völlig durcheinander Christoph
|
|
JasonDelife
      
Beiträge: 81
Windows 7 Professional
C# (Visual Studio 2008 Professional), Java (NetBeans IDE 6.7)
|
Verfasst: Mo 13.07.09 17:23
int / int = int
Grüße, JasonDelife.
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 13.07.09 17:24
Mal sehen, was die Hilfe dazu meint  ...
| / Operator (C# Reference) hat folgendes geschrieben: | | When you divide two integers, the result is always an integer. For example, the result of 5 / 2 is 2. To determine the remainder of 5 / 2, use the modulo operator (%). To obtain a quotient as a rational number or fraction, give the dividend or divisor type float or type double. You can do this implicitly by putting a decimal point after the number, as shown in the following example. [...] |
Bei zwei Variablen musst du eine zuvor nach float/double casten.
_________________ >λ=
|
|
Christoph1972 
      
Beiträge: 690
Erhaltene Danke: 16
VS2015 Pro / C# & VB.Net
|
Verfasst: Mo 13.07.09 17:52
JasonDelife hat folgendes geschrieben : | int / int = int
|
Hm, da finde ich den VB.Net Compiler aber besser, da int / int oft != int . Wenn man da nicht aufpasst, so wie ich, dann gibt das unbrauchbare Ergebnisse. Habt ihr ein Glück das ich keine Steuerung für ein Atomkraftwerk geschrieben habe. Ich habe in der letzten Zeit geglaubt das solche fehler nur mit z.B. VB 1-6.0 möglich sind, da nicht Type-Sicher. Mit VB.Net & Option Strict = On kann das nicht passieren.
Vielen Dank erstmal, wieder was gelernt.
Gruß
Christoph
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mo 13.07.09 19:14
Christoph1972 hat folgendes geschrieben : | | Hm, da finde ich den VB.Net Compiler aber besser, da int / int oft != int . |
Das ist Ansichtssache. Wenn ich "5 durch 2" teile, dann geht es genau genommen nur 2 Mal auf. Wenn (wie oben zitiert) "/" so definiert ist, dass der Ergebnis-Typ gleich den Ausgangstypen ist, dann ist das eben so.
Christoph1972 hat folgendes geschrieben : | | Wenn man da nicht aufpasst, so wie ich, dann gibt das unbrauchbare Ergebnisse. Habt ihr ein Glück das ich keine Steuerung für ein Atomkraftwerk geschrieben habe. |
In der Tat. Wenn jemand nicht aufpasst bei dem, was er macht, und nicht nach den aktuellen gültigen Regeln (nämlich den C#-Regeln) handelt, dann ...
Christoph1972 hat folgendes geschrieben : | | Ich habe in der letzten Zeit geglaubt das solche fehler nur mit z.B. VB 1-6.0 möglich sind, da nicht Type-Sicher. Mit VB.Net & Option Strict = On kann das nicht passieren. |
Das ist eben kein Fehler, sondern so vorgesehen. Also weiß ich wirklich nicht, worüber du dich aufregst. Jürgen
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 13.07.09 19:26
C# und VB mit Strict=On sind gleich typ(un)sicher, erstere Sprache hat für das Problem eben die Operatorüberladung gewählt, letztere zwei getrennte Operatoren. In einer "wirklich typsicheren" Sprache wäre das Problem trotz Überladung nicht aufgetreten, da sie die Zuweisung von button1.Height / button1.Width an double test2 verweigert hätte.
Ob nun überladener Operator oder zwei davon, ob absolut typsicher oder mit impliziten Casts, das läuft letztendlich quasi auf Geschmackssache hinaus  .
_________________ >λ=
|
|
Christoph1972 
      
Beiträge: 690
Erhaltene Danke: 16
VS2015 Pro / C# & VB.Net
|
Verfasst: Mo 13.07.09 22:27
JüTho hat folgendes geschrieben : |
Also weiß ich wirklich nicht, worüber du dich aufregst. Jürgen |
Ich habe mich nur gewundert, aufgeregt nicht  Normalerweise wandelt man ja auch immer um, deshalb habe ich das erst nach ca. 6 Monaten C# bemerkt, war ehr Zufall.
Also, vielen Dank!
|
|
Christoph1972 
      
Beiträge: 690
Erhaltene Danke: 16
VS2015 Pro / C# & VB.Net
|
Verfasst: Sa 25.07.09 09:27
Hi,
ich habe gerade bemerkt das der Compiler bei Int16 eine Meldung rausgibt, das der Typ nicht impliziet konvertiert werden kann. Das muss ich nicht verstehen, oder? Das finde ich inkonsequent, aber nun ja......weiter gehts mit den "wichtigen" Dingen.
Gruß
Christoph
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 25.07.09 12:23
Eine... sehr präzise Problembeschreibung  . Du meinst wahrscheinlich die Tatsache, dass die 8- und 16-Bit-Typen keine eigenen arithmetischen Operatoren besitzen, ergo short + short = int.
Und das ist so, weil, äh...
Erstens rechnet die gesamte CLI so: IL Instructions gibt es einfach nur für 32-Bit, 64-Bit und Floats. Das dürfte vor allem damit zusammenhängen, dass es auf einer modernen CPU keinen Grund gibt, mit kleineren Typen zu rechnen, also Performance.
Zweitens ist es ein C-Erbe, um Overflow-Bugs zu vermeiden. Bei Int32 ist die Gefahr eben einfach etwas geringer  .
Zusammengefasst (so verstehe ich jedenfalls Eric Lipperts Kommentar hier): (S)Byte und (U)Int16 sind in .NET nicht zum Rechnen, sondern nur zum Speichern da.
_________________ >λ=
|
|
InCoBra
      
Beiträge: 43
|
Verfasst: Sa 25.07.09 12:24
Mit Int16 meinst du das wie folgt?
C#-Quelltext 1: 2: 3:
| Int32 Zahl1 = 26; Int32 Zahl2 = 16; Int16 Zahl = Zahl1 / Zahl2; |
Falls ja ist die Erklärung recht einfach:
Int16 hat: Min/Max-Value: -32767 / +32767
Int32 hat: Min/Max-Value: -2147483647 / +2147483647
Das ist also wie als wenn du versuchst eine Zahl aufzuschreiben, die 10 Stellen hat, du hast aber nur Platz für 5 Stellen...
// Zu langsam gewesen...
|
|
Christoph1972 
      
Beiträge: 690
Erhaltene Danke: 16
VS2015 Pro / C# & VB.Net
|
Verfasst: Sa 25.07.09 23:33
Hi zusammen,
ich meinte eigentlich:
Int16 / Int16 = Kompiler Message das nicht impliziet konvertiert werden kann.
bei
Int32 / Int32 = Keine Message, der Rest wird einfach abgeschnitten.
Ok, der Int16 ist nicht zum Rechnen vorgesehen, aber der User=ich kann es trotzdem. Von daher wundert es mich, das der Compiler hier unterschiedlich handelt. Wie gesagt, mit VB.Net ist das nicht möglich, was ich auch gut finde da: Int / Int = oft falsch.
Gruß
Christoph
|
|
|