【问题标题】:Formatting output using ToString使用 ToString 格式化输出
【发布时间】:2016-07-08 00:59:42
【问题描述】:

我正在尝试在 C# 中编辑我的 Fuel Consumed 行以在数字数量之后输出单词“gallons”。我不确定如何操作 ToString 来完成此操作。任何帮助将不胜感激。

    // toString method to display object information
    public override string ToString()
        {  return "\n\nDestination: " + destinationCity +
                "\n\nTotal Miles: " + mileageRoundTrip.ToString("F0") +
                "\n\nFuel Consumed: " + gallonsUsed.ToString("F1") +
                "\n\nFuel Cost Per Gallon: " + gallonsCost.ToString("C") +
                "\n\nTotal Fuel Cost for this Trip: " + totalFuelCost.ToString("C") +
                "\n\nMPG: " + amountMPG.ToString("F0") +
                "\n\nFuel Cost Per Mile: " + costPerMile.ToString("C"); }

【问题讨论】:

  • 您现在面临的问题是什么?

标签: c# format output tostring


【解决方案1】:

与您已经执行的串联类似,您可以在变量之后但在任何换行符之前插入另一个由加号 + 运算符包围的字符串文字,这会将测量单位放在数值之后。例如:

+ " gallons" +

编辑: GreagoryABeamer 在他的帖子中提出了一些很好的观点,即添加了一个强大的、系统的印刷单元实现。我的解决方案不是这样,如果这完全是生产或重复代码,那是一个更好的答案。然而,这个解决方案确实提供了快速使用和不存在开销的机会(我相信字符串文字在 c# 和 c++ 中的编译时连接)。通过变量和文字的一些对齐,代码也可以看起来非常干净。也许是haskish,但有时我更喜欢快速简单。 :)

【讨论】:

  • 有效,但它加剧了额外字符串的创建以返回对象的不同字符串视图,并且仍然使用反模式。
【解决方案2】:

如果您想保留包含两个换行符的原始格式,这应该以更节省内存的方式进行,同时为您提供所需的“加仑”后缀。

var sb = new StringBuilder();
sb.AppendFormat("\n\nDestination: {0}", destinationCity);
sb.AppendFormat("\n\nTotal Miles: {0:F0}", mileageRoundTrip);
sb.AppendFormat("\n\nFuel Consumed: {0:F1} gallons", gallonsUsed);
sb.AppendFormat("\n\nFuel Cost Per Gallon: {0:C}", gallonsCost);
sb.AppendFormat("\n\nTotal Fuel Cost for this Trip: {0:C}", totalFuelCost);
sb.AppendFormat("\n\nMPG: {0}", amountMPG);
sb.AppendFormat("\n\nFuel Cost Per Mile: {0:C}", costPerMile);
return sb.ToString();

【讨论】:

  • 这是最好的解决方案。非常可读,因为代码行与输出行匹配,并且格式化代码被最小化。感谢@Mvarta 扩展我的知识! :)
【解决方案3】:

首先,如果您真的希望 ToString() 在此方法中工作,您应该使用 StringBuilder 而不是连接。不,concats 不会减慢速度,但您在幕后创建了许多额外的字符串来获得您想要的。

至于添加,你可以这样做:

public override string ToString()
{  var builder = new StringBuilder();
   /// more lines here
   builder.Append(gallonCost.ToString("C"));
   builder.Append(" gallons\n\n");
   // etc
   return builder.ToString();
}

您还可以为每个项目创建内部帮助方法,以按照您的意愿对其进行格式化,然后在构建器中将它们连接起来。它更干净。

但是,从架构的角度来看,这种做事方式有很多味道。更改 ToString() 的原因是更改对象的默认表示,而不是格式化用户界面的信息。如果这是动机,你最好通过第二个对象来做到这一点并避免气味,除非你制定一个规则,所有对象的行为方式都相同(仍然不是很好,但一致性更容易遵循)。

如果这是一次性或临时应用程序,您可能会侥幸成功。如果是个人的,那是你自己的事,所以做你想做的事。对于企业软件,我会在代码审查中标记这一点,并强迫某人让我知道他们为什么使用这种特定模式,因为它是非标准的并且可能违反最佳实践。

【讨论】:

    【解决方案4】:

    更新:请参阅@mvarta 的答案,该答案将 format 与 StringBuilder 相结合以获得更易读的解决方案。

    我发现String.format() 更具可读性,因为您将整个模板写成一个字符串:

    return String.format(
        "\n\nDestination: {0}\n\nTotal Miles: {1:F0}\n\nFuel Consumed: {2:F1} gallons\n\nFuel Cost Per Gallon: {3:C}\n\nTotal Fuel Cost for this Trip: {4:C}\n\nMPG: {5:F0}\n\nFuel Cost Per Mile: {6:C}", 
        destinationCity, 
        mileageRoundTrip, 
        gallonsUsed, 
        gallonsCost, 
        totalFuelCost, 
        amounts, 
        costPerMile
    );
    

    要在您想要的任何地方添加加仑,您只需将其写在模板中即可。

    变量在您的模板中用{0}{1} 等表示,其中数字是变量在以下参数中的位置。

    您在 toString 调用中的所有特定格式也使用 {0:C}{1:F1} 等嵌入到模板中。string.Format() 正在为您调用 toString(),因此它不那么冗长。

    https://msdn.microsoft.com/en-us/library/system.string.format(v=vs.110).aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多