Question: For my own implementation of an Equals() method, I want to check a bunch of internal fields. I do it like this:

```
...
_myNullableInt == obj._myNullableInt &&
_myString == obj._myString &&
...

```

I would assume, that this compares the values, including null, for equality not the object address (as a reference euqality compare operation would) because:

It is said so for "predefined value types" [in this MSDN doc here](http://msdn.microsoft.com/en-us/library/53k8ybth%28v=vs.100%29.aspx).
I assume `Nullable<int>` is such a "predefined value type" because of it is in the `System` Namespace according to [this MSDN doc](http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx).

**Am I right to assume that the VALUES are compared here?**

*Note: Unit tests showed "Yes", but I wanted to be reassured by others with this question, just in case I missed something.*

Answer: 
In C#, there's a concept called "Lifted Operators", described in section 7.3.7 of the language specification ([Version 5 download](http://www.microsoft.com/en-gb/download/details.aspx?id=7029)):

> 
> Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following
> 
> 
> 

And specifically:

> 
> For the equality operators
> 
> 
> 

```
==  !=

```

> 
> a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. The lifted form is constructed by adding a single ? modifier to each operand type. The lifted operator considers two null values equal, and a null value unequal to any non-null value. If both operands are non-null, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.
> 
> 
> 

So, since there's an `==` operator defined between `int`s, there's also one defined for `int?`s
If you compare those values it will actually call the [`Nullable<T>.Equals`](http://msdn.microsoft.com/en-us/library/c7b1e4z6%28v=vs.90%29.aspx) method, since both values are nullable ints.

`Nullable<T>.Equals` will eventually call the `==` compare keyword of int, if both values are not null. So in the end, it will indeed check the values.

The code from the [`Equals`](http://referencesource.microsoft.com/#mscorlib/system/nullable.cs#68) method shows this well:

```
public override bool Equals(object other)
{
    if (!this.HasValue)
    {
        return (other == null);
    }
    if (other == null)
    {
        return false;
    }
    return this.value.Equals(other);
}

```