覆盖 .ToString()

Posted

技术标签:

【中文标题】覆盖 .ToString()【英文标题】:override .ToString() 【发布时间】:2010-01-21 13:37:34 【问题描述】:

我想重写 .ToString() 函数,这样每当我得到一个双精度 它只输出小数点后5位。

如何在 override 函数中引用 .ToString 正在处理的对象? 换句话说,我在下面的代码中放了什么 shell 而不是 XXX?

public override string ToString()

    if (XXX.GetType().Name == "Double")
        return (Math.Round(XXX, 5));

【问题讨论】:

【参考方案1】:

为什么不直接使用内置格式?

var pi = 3.14159265m;
Console.WriteLine(pi.ToString("N5"));
-> "3.14159"

作为参考,我喜欢 John Sheehan 的 .NET Format String Quick Reference。

【讨论】:

+1 这是 OP 真正想要使用的。当然,你可以使用作为扩展方法,但这里真的没有意义......【参考方案2】:

你不能覆盖不同类型的方法——基本上你不能阻止double.ToString 做它所做的事情。但是,您可以编写一个方法,该方法采用双精度并对其进行适当的格式化。

【讨论】:

【参考方案3】:

正如 Jon 所指出的,您不能覆盖 Double.ToString。您可以为 double 类型创建一个扩展方法来帮助您执行此操作:

public static class DoubleExtensions 
   public static string ToStringWith5Digits(this double x)  ... 

并像这样使用它:

double d = 10;
string x = d.ToStringWith5Digits(); 

【讨论】:

【参考方案4】:

您可以将格式参数传递给Double.ToString(),指定位数:

double x = 5.12345667;
string s = x.ToString("F5"); // s="5.12345", x.ToString("#.#####") also works

你不能覆盖双精度的 ToString() 函数(它是 struct Double 的成员函数)

【讨论】:

【参考方案5】:

您的 ToString() 函数属于哪个类?通常,您在使用的类中有私有变量。 (但也可以是变量的组合来构建一个 ToString())

例如:(这是伪代码)

class MyClass

  private double dd;
  private string prefix = "MyDouble:";
  ...
  ...
    public override string ToString()
    
        if (dd.GetType().Name == "Double")
        return ( prefix + Math.Round(dd, 5).ToString() );
    

【讨论】:

感谢所有回答。我使用了看起来最简单的方法——使用“F5”格式。不过,如果我想使用不同的方式来格式化我的 double.ToString,例如我想在转换结束时添加一个字符串(“2.345”->“2.345 double”)。我可以将另一个成员添加到具有不同签名的双重结构中,这接近完全独立的功能但更类似于原始功能吗?【参考方案6】:

你不能覆盖,但你可以使用扩展方法

public static string ToRoundString(this double doubleValue)

   return Math.Round(doubleValue, 5).ToString();

用法

public void TestMethod()

   double greatValue = 3;
   string newString = greatVale.ToRoundString();

干杯

【讨论】:

【参考方案7】:

虽然“F5”或“#.#####”解决了原始帖子的细节,但由于标题相当广泛(“覆盖 .ToString()”),我想我会补充说你还可以创建一个重载ToString() 的扩展方法。

所以,例如,一个扩展方法:

    public static string ToString(this double value, int roundTo, string roundSuffix)
    
        string rounded = value.ToString($"#.new String('#', roundTo)");
        if (rounded != value.ToString())
        
            rounded = $"roundedroundSuffix";
        
        return rounded;
    

如果通过,将产生“5.25 已舍入”

double d = 5.2514;
string formatted = d.ToString(2, " was rounded");

如果通过则为“5.2”

double d = 5.2;
string formatted = d.ToString(2, " was rounded");

(只是偶尔会有一些奇怪的用例,有人想做这样的事情!)

您不应该尝试使用与内置ToString() 重载之一具有相同签名的方法覆盖ToString(),因为虽然IDE 会看到它,但它永远不会调用扩展方法(详情见How to call extension method which has the same name as an existing method?)

【讨论】:

以上是关于覆盖 .ToString()的主要内容,如果未能解决你的问题,请参考以下文章

3覆盖toString方法

覆盖 ToString() 时无法获得正确的返回

如何在 F# 中覆盖复合类型中的 ToString?

覆盖 Object.toString 错误

如何在 Java 中正确覆盖 toString()?

Java 对象 始终要覆盖toString