请考虑以下事项:
using System;
namespace ObjectArrayWeirdness
{
public class Program
{
public static object[] Change(object[] set)
{
object[] result = new object[set.Length];
// If the following two lines are replaced with:
// result[0] = "ab";
// then ArrayEquals will evaluate true.
result[0] = "a";
result[0] += "b";
return result;
}
public static bool ArrayEquals(object[] a, object[] b)
{
if (a.Length != b.Length) return false;
for (int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
{
return false;
}
}
return true;
}
static void Main(string[] args)
{
object[] expected = { "ab" };
object[] actual = Change(new object[] { 1 });
Console.WriteLine(ArrayEquals(expected, actual));
}
}
}
输出:
false
result[0].GetType()
的输出:
System.String
我的问题:
ArrayEquals
中的比较是否会因为比较对象引用而不是值而失败?
如果是这种情况,为什么在一步(不使用+=
)分配到result[0]
时正确的字符串成功?
我必须承认我期望正常的字符串比较,因为GetType()
将a[0]
和b[0]
标识为字符串。
答案 0 :(得分:4)
ArrayEquals中的比较是否因为它比较对象引用而不是值而失败?
是
如果是这种情况,为什么在一步(不使用+ =)分配到结果[0]中正确的字符串时它会成功?
这是编译器优化。在编译时声明两个相同的文字字符串时,编译器会将它们折叠为单个对象实例以节省空间。但是如果字符串是在运行时构造的,那么你最终会得到两个独立的字符串对象。
答案 1 :(得分:1)
究竟会发生什么。您正在比较对象引用。但请注意,字符串会覆盖==
和!=
运算符以比较文字。因此,如果将数组项转换为字符串,则您的比较将按预期工作:
if ((string)a[i] != (string)b[i])
{
return false;
}