Here is a basic refresher on value types, reference types, and collections. The following program executes without any assertions failing. Object.ReferenceEquals determines whether the specified Object instances are the same instance. Good stuff to know before an interview.
Update: note John's comment to my post:
To say "myValueType1 and myValueType2 DO NOT point to the same object" is a little bit misleading, because myValueType1 and myValueType2 are just different memory regions on the stack, they're not really 'objects', they're most certainly not 'object references'. The process of passing them as parameters to ReferenceEquals causes them to be boxed (thus becoming 'objects' on the managed heap (complete with object header and GC servicing) with the data from the stack copied into the object on the heap). Another reason why "myValueType1 and myValueType2 DO NOT point to the same object" is a little misleading is that myValueType1 and myValueType2, by virtue of being value types, are not 'pointers', they don't point anywhere. It is true that the value of these value types is stored at different memory addresses, but that's trivially true as the implication of them being local variables.
using System;
using System.Collections;
using System.Diagnostics;
namespace ConsoleApplication43
{
struct ValueType
{
public ValueType(object theObject)
{
this.theObject = theObject;
}
public object theObject;
}
class RefType
{
public RefType(object theObject)
{
this.theObject = theObject;
}
public object theObject;
}
class Class1
{
static void Main()
{
Object myObject = new object();
ValueType myValueType1 = new ValueType(myObject);
RefType myRefType1 = new RefType(myObject);
Hashtable table = new Hashtable();
table.Add("value", myValueType1);
table.Add("ref", myRefType1);
ValueType myValueType2 = (ValueType)table["value"];
RefType myRefType2 = (RefType)table["ref"];
// myRefTYpe1 and myRefType2 point to the same object
Debug.Assert(Object.ReferenceEquals(myRefType1, myRefType2));
// the object reference inside RefType always points to myObject
Debug.Assert(Object.ReferenceEquals(myRefType1.theObject, myObject));
Debug.Assert(Object.ReferenceEquals(myRefType2.theObject, myObject));
// myValueType1 and myValueType2 DO NOT point to the same object
// myValueType is boxed/unboxed ...
Debug.Assert(!Object.ReferenceEquals(myValueType1, myValueType2));
// .. but the copy still contains a reference to the original object
Debug.Assert(Object.ReferenceEquals(myValueType1.theObject, myObject));
Debug.Assert(Object.ReferenceEquals(myValueType2.theObject, myObject));
}
}
}