Провёл очень подробный эксперимент по Equals, ReferenceEquals и ==. Провёл наблюдения и сделал кое-какие выводы. Верны ли мои выводы?
Рано тебе еще такие эксперименты проводить, не зная платформы и ее внутренностей и выводы. 
Ссылочные сравниваются тупо по ссылке,  если не переопределено иное.
1. Мне интересно, когда ты сравнивал два int через ReferenceEquals (а я сразу скажу, будет False),  примерно представлял, что происходит и почему даже на одной переменной всегда будет False? И какие ссылки сравниваются? Указатели на значение в стеке? НЕТ!!!!!! Происходит упаковка и сравниваются два разных объекта, даже на одной переменной.

2.  что int и далее значимые типы не от object наследуются, а от System.ValueType.  У ValueType переопределен Equals. Так и что он делает: сравнивает типы, так как мы передаем object (и опять здравствуй упаковка родная), проверяет возможность побитового сравнения, что относится к примитивным типам и если оно невозможно, для каждого поля (в том числе и приватных) вызывает Equals, причем через рефлексию!!!!!!!!!!! А там если есть значимые поля без переопределенного Equals, здравствуй упаковка.

3. Сравнивать int и long через Equals еще тот изврат,  да у примитивных типов есть перегрузки Equals, типа
public bool Equals(int obj)
{
	return this == obj;
}
те у int перегрузка с int, long c long и тд. если сравнивая через == у тебя сначала приведение типов срабатывает и потом сравнение, а при Equals, так как нет перегрузки необходимой вызывается ValueType(object), срабатывает сначала, она родненькая,  упаковка, а потом сравнение типов и False;

4. Про сравнение структур через ReferenceEquals уже писал.

А мне интересно, вот теперь какие выводы ты для себя сделал? Просто эксперимент и все?
классы сравниваются по хэшу. 
хотя вы можете смухлевать и переопределить хэш
или эквал что в некоторых моментах бывает важно