如何对存储为字符串的实数执行数学计算?
How can I perform a mathematical calculation on real numbers stored as strings?
我有一个 class,其中包含的值有时是货币值(例如 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' 类型的操作数”。 =13=]
所以这是我的逻辑:
如果输入 "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".
pvde.VarianceCraftworks =
(Convert.ToDecimal(pvde.Week2PriceCraftworks) -
Convert.ToDecimal(pvde.Week1PriceCraftworks)).ToString();
问题是基于括号的优先顺序。由于 ToDecimal().ToString().
,它的计算结果为 Decimal - String
如果您将其更改为下面的内容,它应该可以工作
(
Convert.ToDecimal(pvde.Week2PriceCraftworks) -
Convert.ToDecimal(pvde.Week1PriceCraftworks)
).ToString();
所以答案就在你的
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();
}
如果您选择转到 Nullable<T>
等等,这也使您能够更改 HasValue
的实现
您甚至可以更进一步,减去两个已知的十进制字符串:
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);
}
使用这些扩展方法的好处在于,您现在可以用简单的英语阅读正在发生的事情,而不必阅读一堆实现细节。如果由于某种原因解决方案无法正常工作,您还可以测试这些单独的扩展方法,以准确了解哪些部分无法正常工作。
我有一个 class,其中包含的值有时是货币值(例如 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' 类型的操作数”。 =13=]
所以这是我的逻辑:
如果输入 "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".
pvde.VarianceCraftworks =
(Convert.ToDecimal(pvde.Week2PriceCraftworks) -
Convert.ToDecimal(pvde.Week1PriceCraftworks)).ToString();
问题是基于括号的优先顺序。由于 ToDecimal().ToString().
,它的计算结果为 Decimal - String如果您将其更改为下面的内容,它应该可以工作
(
Convert.ToDecimal(pvde.Week2PriceCraftworks) -
Convert.ToDecimal(pvde.Week1PriceCraftworks)
).ToString();
所以答案就在你的
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();
}
如果您选择转到 Nullable<T>
等等,这也使您能够更改 HasValue
的实现
您甚至可以更进一步,减去两个已知的十进制字符串:
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);
}
使用这些扩展方法的好处在于,您现在可以用简单的英语阅读正在发生的事情,而不必阅读一堆实现细节。如果由于某种原因解决方案无法正常工作,您还可以测试这些单独的扩展方法,以准确了解哪些部分无法正常工作。