C#问题:重写ToString方法调用带参私有void方法异常
问题解决:BreakEven计算方法在ToString中无法正常工作
问题背景
你编写了一个用于计算盈亏平衡点的私有void方法,但在ToString方法中调用时出现错误,即使调整参数后仍无法正常执行计算。相关代码如下:
原CalculateBreakEven方法
private void CalculateBreakEven(string companyName, decimal sellingPrice, decimal fixedOverHead, decimal adminSalaries, decimal rawMaterialsPercent, decimal laborCostPercent) { decimal totalVariableCost = rawMaterialsPercent + laborCostPercent; decimal contributionMargin = sellingPrice * totalVariableCost; decimal breakEvenUnits = Math.Ceiling((fixedOverHead + adminSalaries) / contributionMargin); decimal breakEvenDollars = breakEvenUnits * sellingPrice; WriteLine("Break Even units are: ", breakEvenUnits); WriteLine("Break Even sales are: ", breakEvenDollars); }
原ToString方法
public override string ToString() { return string.Format("Selling price: {0:C}\nFixed overhead costs: {1:C}\nFixed cost administrative salaries: {2:C}\nRaw material percent of selling price: {3:C}\nLabor cost percent of selling price: {4:C}\n", CalculateBreakEven(string companyName, decimal sellingPrice, decimal fixedOverHead, decimal adminSalaries, decimal rawMaterialsPercent, decimal laborCostPercent).ToString()); }
核心错误点
void方法无法作为返回值使用:CalculateBreakEven是void类型,没有返回值,不能在string.Format中调用它的ToString(),这会直接导致编译错误。- 参数传递错误:在
ToString中调用方法时,参数不能带类型声明(如decimal sellingPrice),直接使用类的成员变量名即可。 WriteLine占位符缺失:原方法中的WriteLine没有使用占位符{0},导致计算结果无法正常输出。- 盈亏平衡点逻辑错误:贡献毛利的计算逻辑错误,应该是
售价 - 可变成本,即sellingPrice * (1 - totalVariableCost),原代码计算的是可变成本,而非贡献毛利,会导致结果完全错误。 - 格式符使用错误:百分比值应该用
{P}格式符(自动转为百分比显示),而非货币格式{C}。
修正方案
步骤1:修改CalculateBreakEven方法为返回字符串类型
将void改为返回包含计算结果的字符串,这样可以在ToString中直接拼接使用:
private string CalculateBreakEven(string companyName, decimal sellingPrice, decimal fixedOverHead, decimal adminSalaries, decimal rawMaterialsPercent, decimal laborCostPercent) { decimal totalVariableCost = rawMaterialsPercent + laborCostPercent; // 修正贡献毛利计算逻辑:售价减去可变成本占比对应的金额 decimal contributionMargin = sellingPrice * (1 - totalVariableCost); // 避免除以0的情况(如果贡献毛利为0,无法计算盈亏平衡点) if (contributionMargin <= 0) { return "Cannot calculate break-even: Contribution margin is zero or negative.\n"; } decimal breakEvenUnits = Math.Ceiling((fixedOverHead + adminSalaries) / contributionMargin); decimal breakEvenDollars = breakEvenUnits * sellingPrice; return $"Break Even units are: {breakEvenUnits:N0}\nBreak Even sales are: {breakEvenDollars:C}\n"; }
步骤2:修正ToString方法
调整参数传递方式,修正格式符,拼接计算结果:
public override string ToString() { // 直接使用类的成员变量作为参数,无需添加类型声明 string breakEvenInfo = CalculateBreakEven(companyName, sellingPrice, fixedOverHead, adminSalaries, rawMaterialsPercent, laborCostPercent); return string.Format( "Selling price: {0:C}\n" + "Fixed overhead costs: {1:C}\n" + "Fixed cost administrative salaries: {2:C}\n" + "Raw material percent of selling price: {3:P}\n" + "Labor cost percent of selling price: {4:P}\n" + "{5}", sellingPrice, fixedOverHead, adminSalaries, rawMaterialsPercent, laborCostPercent, breakEvenInfo ); }
额外说明
- 确保
companyName、sellingPrice等变量是当前类的成员变量,否则需要调整参数来源。 - 添加了贡献毛利为0的判断,避免运行时出现除以0的异常。
内容的提问来源于stack exchange,提问作者xchangecode
相关产品推荐
相关产品推荐

