2008-07-31 7 views
543

Ich möchte eine Spur-Leiste verwenden, um die Deckkraft eines Formulars zu ändern.Wenn wir Deckkraft auf ein Formular anwenden, sollten wir einen Dezimalwert oder einen doppelten Wert verwenden?

Dies ist mein Code:

decimal trans = trackBar1.Value/5000; 
this.Opacity = trans; 

Wenn ich die Anwendung zu erstellen, es wird folgende Fehler gibt:

Cannot implicitly convert type 'decimal' to 'double' .

Ich versuchte trans und double verwenden, aber dann wird die Steuerung funktioniert nicht. Dieser Code funktionierte in einem früheren VB.NET-Projekt einwandfrei.

+8

auch Dezimal kann nicht so breit Wert als Double darstellen. Dezimal kann nur bis zu +/- 7.9228162514264337593543950335E + 28; während ein Double kann bis zu +/- 1.79769313486232E + 308 – TraumaPony

Antwort

391

Eine explizite Umwandlung wie diese zu verdoppeln ist nicht notwendig:

double trans = (double) trackBar1.Value/5000.0; 

die ständige Identifizierung als 5000.0 (oder als 5000d) genügt:

double trans = trackBar1.Value/5000.0; 
double trans = trackBar1.Value/5000d; 
53

Es ist wie this.Opacity klingt, ist ein Doppel Wert, und der Compiler mag es nicht, dass Sie versuchen, einen Dezimalwert in ihn zu stopfen.

112

Eine generische Antwort auf die allgemeine Frage „Dezimal vs Doppel?“: Dezimal für monetäre Berechnungen die Genauigkeit zu erhalten, Doppel für wissenschaftliche Berechnungen, die von kleinen Unterschieden nicht betroffen erhalten. Da Double ein Typ ist, der nativ für die CPU ist (interne Repräsentation ist in Basis 2 gespeichert), führen Berechnungen mit Double besser als Dezimal aus (was intern in Basis 10 dargestellt wird).

55

Meiner Meinung nach ist es wünschenswert, so explizit wie möglich zu sein. Dies erhöht die Klarheit des Codes und hilft Ihren Programmierkollegen, die sie eventuell lesen können.

Zusätzlich zu (oder anstelle von) einem .0 an die Nummer anhängen, können Sie decimal.ToDouble() verwenden.

Hier sind einige Beispiele:

// Example 1 
double transperancy = trackBar1.Value/5000; 
this.Opacity = decimal.ToDouble(transperancy); 

// Example 2 - with inline temp 
this.Opacity = decimal.ToDouble(trackBar1.Value/5000); 
74

Ihr Code arbeitete in VB.NET in Ordnung, weil es implizit alle Abgüsse der Fall ist, während C# sowohl implizite und explizite diejenigen hat.

In C# ist die Konvertierung von Dezimal zu Doppel explizit, da Sie die Genauigkeit verlieren. Zum Beispiel kann 1.1 nicht genau als ein Doppel ausgedrückt werden, kann aber als Dezimalzahl (siehe "Floating point numbers - more inaccurate than you think" aus dem Grund warum).

In VB wurde die Konvertierung für Sie vom Compiler hinzugefügt:

decimal trans = trackBar1.Value/5000m; 
this.Opacity = (double) trans; 

Der (double) ausdrücklich in C# angegeben werden muss, kann aber mehr der von VB impliziert sein 'nachsichtig' Compiler.

73

Warum teilen Sie durch 5000? Stellen Sie einfach die Minimum- und Maximum-Werte für den TrackBar zwischen 0 und 100 ein und teilen Sie dann den Wert für den Prozentsatz der Opazität durch 100.Das Minimum 20 Beispiel verhindert, dass das folgende Formular aus immer völlig unsichtbar:

private void Form1_Load(object sender, System.EventArgs e) 
{ 
    TrackBar1.Minimum = 20; 
    TrackBar1.Maximum = 100; 

    TrackBar1.LargeChange = 10; 
    TrackBar1.SmallChange = 1; 
    TrackBar1.TickFrequency = 5; 
} 

private void TrackBar1_Scroll(object sender, System.EventArgs e) 
{ 
    this.Opacity = TrackBar1.Value/100; 
} 
+3

Würde dies nicht nur verschieben das Problem herum? Anstatt ein Problem mit '5000' zu haben, würde OP ein Problem mit' 100' haben? – jww

45

Sie 5000.0 statt 5000 verwenden sollten.

56

Sie haben zwei Probleme. Zuerst benötigt Opacity einen doppelten, keinen Dezimalwert. Der Compiler weist Sie darauf hin, dass es zwar eine Konvertierung zwischen Dezimal und Doppel gibt, es sich jedoch um eine explizite Konvertierung handelt, die Sie angeben müssen, damit sie funktioniert. Der zweite ist, dass TrackBar.Value ein ganzzahliger Wert ist und ein int durch einen int zu einem int führt, unabhängig davon, welcher Typ von Variable Sie ihm zuweisen. In diesem Fall gibt es eine implizite Umwandlung von int in dezimal oder double - weil es keinen Genauigkeitsverlust bei der Umwandlung gibt - also reklamiert der Compiler nicht, aber der Wert, den Sie bekommen, ist immer 0, vermutlich, da trackBar.Value ist immer weniger als 5000. Die Lösung besteht darin, den Code so zu ändern, dass Double (der native Typ für Opazität) verwendet wird, und Fließkomma-Arithmetik auszuführen, indem die Konstante explizit verdoppelt wird - was die Arithmetik fördert - oder Casting trackBar.Value verdoppelt , die das Gleiche tun - oder beides. Oh, und Sie brauchen die Zwischenvariable nicht, wenn sie nicht woanders verwendet wird. Ich schätze, der Compiler würde es sowieso optimieren.

trackBar.Opacity = (double)trackBar.Value/5000.0; 
44

Die Opacity Eigenschaft ist vom Typ double:

double trans = trackBar1.Value/5000.0; 
this.Opacity = trans; 

oder einfach:

this.Opacity = trackBar1.Value/5000.0; 

oder:

this.Opacity = trackBar1.Value/5000d; 

Beachten Sie, dass ich 5000.0 bin mit (oder 5000d), um eine doppelte Division zu erzwingen, da trackBar1.Value eine Ganzzahl ist und eine ganzzahlige Division durchführt und das Ergebnis eine ganze Zahl wäre.

42

Sie verwenden WinForms Unter der Annahme, ist Form.Opacity vom Typ double, so dass Sie verwenden sollten:

double trans = trackBar1.Value/5000.0; 
this.Opacity = trans; 

Sofern Sie den Wert an anderer Stelle benötigen, ist es einfacher ist, zu schreiben:

this.Opacity = trackBar1.Value/5000.0; 

Der Grund für die Steuerung funktioniert nicht, wenn Sie Ihren Code geändert einfach ein Doppel zu sein, weil Sie hatte:

double trans = trackbar1.Value/5000; 

was die 5000 als eine ganze Zahl interpretiert, so dass Ihr trans Wert immer Null war. Durch explizite Angabe des Gleitkommazahlenwertes durch Addition des .0 kann der Compiler diesen nun als Doppel interpretieren und die richtige Berechnung durchführen.

38

Die beste Lösung ist:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000); 
37

Da Opacity ein doppelter Wert ist, würde ich eine doppelte von Anfang an verwenden Sie einfach und schon gar nicht werfen, aber sicher sein, ein Doppel zu verwenden, wenn so Sie don Dividieren ‚t verlieren irgendeiner Präzision

Opacity = trackBar1.Value/5000.0; 
31
this.Opacity = trackBar1.Value/5000d; 
Verwandte Themen