【问题标题】:Convert.ToString behaves differently for "NULL object" and "NULL string"Convert.ToString 对于“NULL 对象”和“NULL 字符串”的行为不同
【发布时间】:2014-01-14 15:28:40
【问题描述】:

我在 C# 控制台应用程序中有 foo (object) 和 foo2 (string)。 Code 2 抛出异常,而 Code 1 工作正常。

您能否解释一下为什么会这样(参考 MSDN)?

// 代码1

object foo = null;
string test = Convert.ToString(foo).Substring(0, Convert.ToString(foo).Length >= 5 ? 5 : Convert.ToString(foo).Length);

// 代码2

string foo2 = null;
string test2 = Convert.ToString(foo2).Substring(0, Convert.ToString(foo2).Length >= 5 ? 5 : Convert.ToString(foo2).Length);

【问题讨论】:

  • “你能解释一下为什么会这样吗(参考 MSDN)?” - I just did that on your previous question.
  • @CodeCaster 对不起。从你的解释中我无法理解。
  • 没问题,你可以对我的评论发表评论,但现在你已经得到了答案。 ;-)

标签: c#


【解决方案1】:

来自Convert.ToString(string)的文档:

返回值
类型:System.String
原样返回。

所以null 输入将导致null 返回值。

来自Convert.ToString(object)的文档:

返回值
类型:System.String
value 的字符串表示形式,如果 value 为 null,则为 String.Empty

(这里“Nothing”的意思是“null”。)

所以null输入会产生一个空字符串(非空引用)返回值。

【讨论】:

  • @Lijo:是的,这实际上是两种不同的方法,而不是一种行为不同的方法。具有相同名称但参数列表不同的相同类型(例如类)中的方法称为重载。见Member Overloading
  • ..or String.Empty if value is Nothing...or String.Empty if value is null. 换成了:)
  • @SonerGönül:谢谢 - 看起来 MSDN 现在不仅对代码 sn-p 是上下文敏感的,而且对那种文档也是如此。很有趣。
  • 谢谢...但这有点奇怪。
【解决方案2】:

因为:

这是 Convert.ToString(object value) 的实现

public static string ToString(Object value) {
    return ToString(value,null);
}

public static string ToString(Object value, IFormatProvider provider) { 
    IConvertible ic = value as IConvertible; 
    if (ic != null)
        return ic.ToString(provider); 
    IFormattable formattable = value as IFormattable;
    if (formattable != null)
        return formattable.ToString(null, provider);
    return value == null? String.Empty: value.ToString(); 
}

这是 Convert.ToString(string value)

public static String ToString(String value) {
        Contract.Ensures(Contract.Result<string>() == value);  // We were always skipping the null check here.
        return value; 
    }

【讨论】:

    【解决方案3】:

    来自Link

    这里有 2 个 ToString 重载

    Convert.ToString(object o);
    Convert.ToString(string s);
    

    C# 编译器本质上会尝试选择最具体的重载,该重载将与输入一起工作。空值可转换为任何引用类型。在这种情况下,字符串比对象更具体,因此将被选为获胜者。

    在作为对象的 null 中,您已将表达式的类型固化为对象。这意味着它不再与字符串重载兼容,编译器会选择对象重载,因为它是唯一剩余的兼容对象。

    C# 语言规范的第 7.4.3 节详细介绍了这种打破平局的工作原理。

    【讨论】:

      猜你喜欢
      • 2017-02-17
      • 2014-11-30
      • 1970-01-01
      • 2020-03-09
      • 2012-09-21
      • 1970-01-01
      • 2018-06-08
      • 2014-08-17
      • 1970-01-01
      相关资源
      最近更新 更多