【问题标题】:Difference between Convert.ToString(str) and str?.ToString() ?? ""Convert.ToString(str) 和 str?.ToString() 之间的区别 ?? “”
【发布时间】:2019-04-27 21:08:36
【问题描述】:

这两种方法有什么区别吗?

static void Main(string[] args)
{
    object str = null;

    string test1 = str?.ToString() ?? "";

    string test2 = Convert.ToString(str);
}

编辑 1:

正如@Fabio 指出的,我们有第三种可能的方法:

string test3 = $"{str}";

【问题讨论】:

标签: c# performance optimization


【解决方案1】:

所以,直接回答您的问题:任何方法之间都没有区别。 IFormatProvider 过载情况会有所不同。

现在进入细节:

Convert.ToString 将尝试调用IConvertibleIFormattable 接口(按此顺序),然​​后返回到基础object.ToString。所以如果你传递的东西没有实现任何这些接口(或null,你不能在其上调用任何成员方法),这与简单的object.ToString没有区别。

现在字符串插值是复合格式化的一种情况(字符串插值实际上相当于调用string.Format)。这将只调用IFormattable 接口实现,然后回退到object.ToString。同样,如果某些东西没有实现接口(或null),没有区别。

为了让事情变得更复杂,这两个方法都包含一个采用IFormatProvider 参数的重载。对于Convert.ToString,如果对象实现IConvertible 接口,该方法将尝试调用IConvertible.ToString(IFormatProvider)。然后它会尝试IFormattable.ToString(String, IFormatProvider),如果失败则回退到object.ToString()

在复合格式的情况下,它会尝试调用IFormatProvider.GetFormat方法,然后使用返回的ICustomFormatter。如果失败,它会继续使用 IFormattable 并最终退回到 object.ToString

当涉及到null 值时,使用IFormatProvider 时可能会有所不同。由于Convert.ToString 尝试调用IConvertible 实现,并且您不能真正调用null 上的任何内容,因此它将null 视为特殊情况并返回string.Empty。但是,复合格式调用 ICustomFormatter.Format 时将对象作为参数,因此如果您使用以不同方式处理 nullICustomFormatter,您可以获得不同的结果!您可以使用this code snippet 进行验证(免责声明:实现IFormatProvider 不是最聪明的方法,但它可以作为示例)。

这里是the MSDN doc for Convert.ToString

这里是the MSDN doc for composite formatting(请参阅处理订单部分)。

【讨论】:

    【解决方案2】:

    如果我们使用 Convert.ToString 那么它可以处理空值。但是 Tostring 不能处理空值

    例如:

    object str=null;
    System.out.print(convert.ToString(str)); //shows null value
    String s=str.ToString();
    System.out.print(s); //throws exception
    

    【讨论】:

      【解决方案3】:

      Convert.ToString 在调用基 Object.ToString 之前尝试使用 IFormattable 和 IConvertible 接口 示例

      class FormattableType : IFormattable
      {
          private double value = 0.42;
      
          public string ToString(string format, IFormatProvider formatProvider)
          {
              if (formatProvider == null)
              {
                  // ... using some IOC-containers
                  // ... or using CultureInfo.CurrentCulture / Thread.CurrentThread.CurrentCulture
                  formatProvider = CultureInfo.InvariantCulture;
              }
      
              // ... doing things with format
              return value.ToString(formatProvider);
          }
      
          public override string ToString()
          {
              return value.ToString();
          }
      }
      

      结果:

      Convert.ToString(new FormattableType()); // 0.42
      new FormattableType().ToString();        // 0,42
      

      【讨论】:

        猜你喜欢
        • 2011-02-19
        • 2016-10-07
        • 2015-07-17
        • 1970-01-01
        • 2021-12-08
        • 2019-10-17
        • 2016-04-25
        • 2016-08-05
        • 1970-01-01
        相关资源
        最近更新 更多