关于ReferenceEquals(object a, object b)的问题

昨天跟几个同事一起讨论了下object.ReferenceEquals(object a, object b)方法, 其中有这样一个问题:

 object c = "foo";
 
string d = "foo";

 
bool i = ReferenceEquals(c, d); //return true

为什么返回的是true?
c和d都是调用了string的赋值构造函数,string的赋值构造函数是不会在堆上申请空间的。那么如果string赋值构造函数不会在堆上申请空间,又不是指针,何来引用,看了下这段代码的IL,

  IL_0000:  nop
  IL_0001:  ldstr      
"foo"
  IL_0006:  stloc.
0
  IL_0007:  ldstr      
"foo"
  IL_000c:  stloc.
1
  IL_0013:  ldloc.
1
  IL_0014:  ldloc.
0
  IL_0015:  call       
bool [mscorlib]System.Object::ReferenceEquals(object,
                                                                     
object)


的确都是在栈上分配的, 并且第一个"foo"和第二个"foo"进栈的顺序是不一样的,引用怎么可能一样?
另外, object类的ReferenceEquals(object a, object b)的实现是这样的:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static bool ReferenceEquals(object objA, object objB)
{
    
return (objA == objB);
}

只做简单的"=="比较. 百思不得其解.. 最后一个同事在网上找到这样一句话:
 

.NET 运行时在应用程序域中保留了一个字符串常值池, 当它将一个程序集加载到应用程序域中时,将该程序集的字符串常值与应用程序域的字符串常值池合并,从而避免了字符串常值的重复。(这样所有字符串常值只有一个副本,就可以对字符串常值进行引用比较,而且因为引用只需比较地址即可,所以比值比较快得多。)

posted on 2008-05-23 12:54  Daniel Luo  阅读(437)  评论(0编辑  收藏  举报

导航