2016-06-30 14 views
0

Ich habe eine Klasse, die Werte enthält, die manchmal Geldwerte sind (wie 1,25, 2,50, 10,00 usw.), aber auch die Zeichenfolge "N/A"; so werden sie als String deklariert:Wie kann ich eine mathematische Berechnung für reelle Zahlen durchführen, die als Strings gespeichert sind?

public class PriceVarianceDataExtended 
{ 
    public String ShortName { get; set; } 
    public String ItemCode { get; set; } 
    public String Description { get; set; } 

    public string Week1PriceCraftworks { get; set; } 
    public string Week2PriceCraftworks { get; set; } 
    public string VarianceCraftworks { get; set; } 

    public string Week1PriceChophouse { get; set; } 
    public string Week2PriceChophouse { get; set; } 
    public string VarianceChophouse { get; set; } 

    public string Week1PriceGordonBiersch { get; set; } 
    public string Week2PriceGordonBiersch { get; set; } 
    public string VarianceGordonBiersch { get; set; } 

    public string Week1PriceOldChicago { get; set; } 
    public string Week2PriceOldChicago { get; set; } 
    public string VarianceOldChicago { get; set; } 

    public string Week1PriceOldChiFranchise { get; set; } 
    public string Week2PriceOldChiFranchise { get; set; } 
    public string VarianceOldChiFranchise { get; set; } 

    public string Week1PriceRockBottom { get; set; } 
    public string Week2PriceRockBottom { get; set; } 
    public string VarianceRockBottom { get; set; } 
} 

jedoch dieser Code bedeutete den monetären Wert zu speichern (als String), wo der Sinn macht, und ansonsten die val auf "N/A":

private string NOT_APPLICABLE = "N/A"; 
. . . 
if (pvde.Week1PriceCraftworks != NOT_APPLICABLE && 
    pvde.Week2PriceCraftworks != NOT_APPLICABLE) 
{ 
    pvde.VarianceCraftworks = 
     Convert.ToDecimal(pvde.Week2PriceCraftworks) - 
     Convert.ToDecimal(pvde.Week1PriceCraftworks).ToString(); 
} 
else 
{ 
    pvde.VarianceCraftworks = NOT_APPLICABLE; 
} 

... ausfällt, sagt mir, "Operator '-' nicht auf die Operanden vom Typ 'dezimal' und 'string' angewendet werden kann" kompilieren

Also das ist meine Logik:

Wenn der "if" -Block eingegeben wird, bedeutet das, dass Week1PriceCraftworks und Week2PriceCraftworks numerische Werte wie Strings wie "5.00" und "3.14"

enthalten. Ich konvertiere dann "5.00" zu 5 und "3.14" zu 3.14 Verwenden der Convert.ToDecimal() -Aufrufe. Dies sollte einen Wert von 1,86 ergeben, der dann in eine Zeichenfolge ("1,86") umgewandelt wird, so dass der richtige Datentyp pvde.VarianceCraftworks zugewiesen wird.

Aber vernünftig und unkompliziert, wie mir scheint, bekomme ich das irr msg. Was ist falsch an meinem Ansatz?

BTW, die „week1“ und „week2“ Werte werden durch den Aufruf einer Methode, die auf diese Weise endet:

return price ?? NOT_APPLICABLE; 

... so was in Week1PriceCraftworks enthalten ist und Week2PriceCraftworks sind entweder reale Werte (gespeichert als Zeichenfolgen) oder "N/A".

+6

Versuchen Sie '()': '(Convert.ToDecimal (pvde.Week2PriceCraftworks) - Convert.ToDecimal (pvde.Week1PriceCraftworks))' .ToString(); – AlexD

+2

Warum verwenden Sie nicht einfach NULL-Werte? –

+0

@AlexD: Das hat funktioniert; mach es eine Antwort, wenn du willst. –

Antwort

1

Das Problem ist die Rangfolge basierend auf Ihrer Klammer. Es wird auf Decimal - String basierend auf ToDecimal(). ToString() ausgewertet.

Wenn Sie es die folgenden ändern liegt die Antwort So

(
    Convert.ToDecimal(pvde.Week2PriceCraftworks) - 
    Convert.ToDecimal(pvde.Week1PriceCraftworks) 
).ToString(); 
1
pvde.VarianceCraftworks = 
     (Convert.ToDecimal(pvde.Week2PriceCraftworks) - 
     Convert.ToDecimal(pvde.Week1PriceCraftworks)).ToString(); 
+0

Was war los mit meiner Antwort? –

+1

Bitte fügen Sie eine Erklärung hinzu, warum dieser Code dem OP hilft. Dies wird helfen, eine Antwort zu liefern, von der zukünftige Zuschauer lernen können. Weitere Informationen finden Sie unter [Antwort]. –

+0

aber meine Antwort ist praktisch gleich dem angenommenen –

2

funktionieren sollte in Ihrem

pvde.VarianceCraftworks = 
     Convert.ToDecimal(pvde.Week2PriceCraftworks) - 
     Convert.ToDecimal(pvde.Week1PriceCraftworks).ToString(); // to string is called during the operation rather than afterwards 

Zweitens würde ich einige Code ausrücken in Erweiterungsmethoden:

pvde.Week1PriceCraftworks != NOT_APPLICABLE 

bis

public static bool HasValue(this string value) 
{ 
    return value != NOT_APPLICABLE; 
} 

und

Convert.ToDecimal(pvde.Week2PriceCraftworks) 

zu

public static decimal ToDecimal(this string value) 
{ 
    return Convert.ToDecimal(value); 
} 

Dann wird es lesen viel schöner:

private string NOT_APPLICABLE = "N/A"; 
. . . 
pvde.VarianceCraftworks = NOT_APPLICABLE; 
if (pvde.Week1PriceCraftworks.HasValue() && 
    pvde.Week2PriceCraftworks.HasValue()) 
{ 
    pvde.VarianceCraftworks = 
     (pvde.Week2PriceCraftworks.ToDecimal() - 
     pvde.Week1PriceCraftworks.ToDecimal()).ToString(); 
} 

Dies gibt Ihnen auch die Möglichkeit, die Umsetzung von HasValue zu ändern, wenn Sie wählen um zu gehen Nullable<T> usw. usw.

Sie noch einen Schritt weiter gehen können, mit zwei Strings bekannt dezimal Subtraktion:

public static string SubtractDecimals(this string value, string subtractValue) 
{ 
    return (value.ToDecimal() - value.ToDecimal()).ToString(); 
} 

So jetzt:

private string NOT_APPLICABLE = "N/A"; 
. . . 
pvde.VarianceCraftworks = NOT_APPLICABLE; 
if (pvde.Week1PriceCraftworks.HasValue() && 
    pvde.Week2PriceCraftworks.HasValue()) 
{ 
    pvde.VarianceCraftworks = pvde.Week2PriceCraftworks.SubtractDecimal(pvde.Week1PriceCraftworks); 
} 

Die schöne an diese Erweiterungsmethoden zu verwenden ist, dass man jetzt lesen was läuft in einfachem Englisch, anstatt eine Reihe von Implementierungsdetails zu lesen. Sie können diese einzelnen Erweiterungsmethoden auch testen, um genau zu sehen, welcher Teil nicht wie erwartet funktioniert, wenn die Lösung aus irgendeinem Grund nicht funktioniert.

+0

Nicht kompilieren. –

+0

Was nicht? Ich schrieb das aus der Spitze meines Kopfes –

+1

Dieser Trick funktioniert nie. –