0

我有一个类,它包含的值有时是货币值(例如 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;
}

...编译失败,告诉我,“运算符'-'不能应用于'十进制'和'字符串'类型的操作数

所以这是我的逻辑:

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

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

但是,在我看来,这是合理而直接的,我得到了那个错误的消息。我的方法有什么问题?

顺便说一句,“week1”和“week2”值是通过调用以这种方式结束的方法来设置的:

return price ?? NOT_APPLICABLE;

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

4

3 回答 3

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>etc. 等的实现。

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

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

使用这些扩展方法的好处是您现在可以用简单的英语阅读正在发生的事情,而不必阅读一堆实现细节。如果由于某种原因解决方案无法正常工作,您还可以测试这些单独的扩展方法,以确切了解哪个部分没有按照您的预期工作。

于 2016-06-30T17:45:29.327 回答
1

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

如果您将其更改为以下内容,它应该可以工作

(
  Convert.ToDecimal(pvde.Week2PriceCraftworks) - 
  Convert.ToDecimal(pvde.Week1PriceCraftworks)
).ToString();
于 2016-06-30T17:45:01.573 回答
1
pvde.VarianceCraftworks = 
        (Convert.ToDecimal(pvde.Week2PriceCraftworks) - 
        Convert.ToDecimal(pvde.Week1PriceCraftworks)).ToString();
于 2016-06-30T17:44:20.670 回答