ReferenceEquals and Nullable<T>

While writing a unit test, I wanted to use Assert.AreSame(..) against a Nullable<T> type and I got unexpected results. Then I realized that the below code fails:

int? k = 10;
Assert.IsTrue(ReferenceEquals(k, k));

What is happening here?

Also, how can I make sure my method is returning the very same instance I passed to the mock/stub and not just doing return 10?

Edit:

I usually do the following to make sure I'm getting consistent results in my unit tests:

//Arrange
var result = new string(new[] {'1', '2', '3'});
mock.SetUp(x => x.Method("something").Returns(result);

//Act here

//Assert
Assert.AreSame(result, instance.ValueAssigned);

If I do return "123" inside Method(..), the above test will fail. I was trying to find a way of doing the same with Nullable.

Jon Skeet
people
quotationmark

What is happening here?

Both arguments are being boxed, to different objects.

Imagine your code is actually this:

int? k = 10;
object x = k; // Boxing operation 1
object y = k; // Boxing operation 2
Assert.IsTrue(ReferenceEquals(x, y));

Don't forget that nullable value types are still value types - so they get boxed when you convert them to reference type expressions.

Also, how can I make sure my method is returning the very same instance I passed to the mock/stub and not just doing return 10?

For value types, that question simply doesn't make sense. Basically, use Assert.AreSame for reference types, and Assert.AreEqual for value types. Note that this is independent of nullability. Assert.AreSame(10, 10) will fail too.

people

See more on this question at Stackoverflow