如何对存储为字符串的实数进行数学计算?

时间:2016-06-30 17:39:49

标签: c# decimal type-conversion string-math

我有一个类,其中包含有时是货币值的值(例如1.25,2.50,10.00等),但也可以是字符串“N / A”;因此,它们被声明为字符串:

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; }
}

但是,此代码用于将货币值(作为字符串)存储在有意义的位置,否则将val设置为“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;
}

...无法编译,告诉我,“运算符' - '不能应用于'decimal'和'string'类型的操作数”

所以这是我的逻辑:

如果输入“if”块,则表示Week1PriceCraftworks和Week2PriceCraftworks包含表示为字符串的数值,例如“5.00”和“3.14”

然后我使用Convert.ToDecimal()调用将“5.00”转换为5并将“3.14”转换为3.14。这应生成1.86的值,然后将其转换为字符串(“1.86”),以便将正确的数据类型分配给pvde.VarianceCraftworks。

但是,在我看来,合理而直截了当,我得到了错误的信息。我的方法出了什么问题?

BTW,通过调用以这种方式结束的方法来设置“week1”和“week2”值:

return price ?? NOT_APPLICABLE;

...所以Week1PriceCraftworks和Week2PriceCraftworks中包含的内容是实数值(存储为字符串)或“N / A”。

3 个答案:

答案 0 :(得分:2)

所以答案就在你的

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

其次,我会将一些代码移到扩展方法中:

pvde.Week1PriceCraftworks != NOT_APPLICABLE

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

Convert.ToDecimal(pvde.Week2PriceCraftworks)

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

然后它会读得更好:

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();
}

如果您选择转到HasValue等等,这也可以让您更改Nullable<T>的实施。

你甚至可以更进一步,减去两个已知的十进制字符串:

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

现在:

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

使用这些扩展方法的好处是你现在可以用简单的英语阅读正在发生的事情,而不必阅读一堆实现细节。您还可以测试这些单独的扩展方法,以便在出于某种原因解决方案无法正常工作的情况下,确切地了解哪些部分无法正常工作。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

问题是基于括号的优先顺序。由于ToDecimal()。ToString(),它正在评估为Decimal - String。

如果将其更改为以下内容,则应该

(
  Convert.ToDecimal(pvde.Week2PriceCraftworks) - 
  Convert.ToDecimal(pvde.Week1PriceCraftworks)
).ToString();