【问题标题】:Calling ToString() on a Reference Type [closed]在引用类型上调用 ToString() [关闭]
【发布时间】:2012-11-07 16:59:02
【问题描述】:

给定两个对象数组,我需要比较两者之间的差异(当转换为字符串时)。我已将代码简化为以下,但问题仍然存在:

public void Compare(object[] array1, object[] array2) {
    for (var i = 0; i < array1.Length; i++) {
        var value1 = GetStringValue(array1[i]);
        var value2 = GetStringValue(array2[i]);
    }
}

public string GetStringValue(object value) {
    return value != null && value.ToString() != string.Empty ?
        value.ToString() : "No Value";
}

无论我抛出什么对象数组,代码都能正常执行。但是,如果数组中的一项是引用类型,那么会以某种方式更新引用。这会导致以后出现问题。

似乎在针对对象引用调用 ToString() 时会发生这种情况。我已将 GetStringValue 方法更新为以下内容(确保对象是值类型或字符串)并且问题消失了。

public string GetStringValue(object value) {
    return value != null && (value.GetType().IsValueType || value is string)
        && value.ToString() != string.Empty ? value.ToString() : "No Value";
}

但这只是一个临时的 hack,因为我希望能够覆盖我的引用类型上的 ToString() 方法并比较它们。

如果有人能解释为什么会发生这种情况并提供潜在的解决方案,我将不胜感激。谢谢

编辑

帮助进一步解释我的申请。这段代码取自 NHibernate 事件监听器。我认为问题在于 NHibernate 在类周围添加了自己的包装器来处理延迟加载。这是它抛出的错误:

集合 [*] 没有被 flush() 处理

【问题讨论】:

  • “以某种方式更新了参考”是什么意思?如果您可以提供一个简短但完整的程序来演示该问题,那将有很大帮助。 (你的代码也比它需要的更令人困惑 - 为什么调用 ToString() 两次?如果你希望结果是一个空字符串,如果 ToString() 返回一个空字符串,你不需要做任何替换.. .)
  • 您能否更准确地解释一下“参考已更新”是什么意思?
  • 您能解释一下“参考资料已更新”是什么意思吗?
  • 如果value.toString() != string.Empty失败了就返回空字符串,为什么还要测试它?
  • 你是什么意思参考已更新。顺便说一句,所有数组项都被视为引用,甚至是值类型,因为装箱

标签: c# object tostring reference-type


【解决方案1】:

听起来在引用类型的 ToString() 方法中很可能会产生副作用,这通常是不好的做法,因为这是 .NET 框架经常使用的方法。

如果出现这种情况,必须满足以下条件:

  • 您正在使用您自己或其他第 3 方构建的自定义类。
  • 调用 ToString() 时会发生对象的某些修改。

要验证这一点,您只需创建引用类型的实例并在其上调用 ToString()。查看对象是否已更改(GetHashCode() 可能是确定这一点的一种方法)。或者你可以检查代码...

【讨论】:

  • 这实际上是一个评论,而不是一个答案,因为它提出了一个澄清问题。
  • @Servy:根据帖子中的当前信息,这是一个答案...通常一个问题可以有很多答案,我会将澄清问题更改为验证这是否是错误的方法与否。
  • 如果问题中没有足够的信息来给出高质量的答案,那么您根本不回答,您可以在 cmets 中提问直到他们得到回答,或者您投票关闭为“不一个真正的问题”,如果您觉得没有人可以用所提供的信息回答它。您不会发布澄清问题或低质量答案作为答案。
  • 你有你要比较的这些对象的来源吗?如果是这样,您应该采取利用 IEqualityComparer 的方法。无论哪种方式,您正在转换的其中一种类型都可能覆盖了 ToString 方法并在此过程中改变了自身。最后,使用 Convert.ToString(object) 将更有效地替换您的 GetStringValue 方法。最后,不清楚您的 Compare 方法返回什么,因为它的返回类型是 void 并且您没有列出它的其余部分。
  • 谢谢我将此标记为答案,因为它不仅帮助我识别问题,而且使用您创建新实例的建议找到了一个很好的解决方案。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 2012-08-01
  • 2023-03-17
  • 2018-08-10
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
相关资源
最近更新 更多