Упорядочить объекты .NET по ссылке, а не по значению - PullRequest
1 голос
/ 08 ноября 2010

Как заказать (сравнить) объекты .NET по ссылке? Я бы использовал это, чтобы эффективно определить, содержат ли две коллекции .NET одинаковые экземпляры (по ссылке, а не по значению).

Другим способом формулировки этого вопроса может быть обращение к реализации IComparer, которая использует сравнение ссылок, а не сравнение значений.

Примечание в Java, я бы использовал System.identityHashCode().

Ответы [ 4 ]

5 голосов
/ 08 ноября 2010

Использовать Object.ReferenceEquals () .

Обратите внимание, что сравнение ссылочных типов с использованием оператора == также делает то, что вы хотите, если только оператор равенства не переопределен в этих типах.

EDIT: System.Object имеет GetHashCode () , который работает так же, как Java hashCode(). Его поведение может быть достаточно похоже на identityHashCode(), чтобы удовлетворить ваши потребности, но я не понимаю, как сравнение ссылок или хэш-кодов будет отражать фактическое значение ваших объектов.

1 голос
/ 08 ноября 2010

Вы не можете буквально упорядочить объекты .NET по ссылке ... очевидно, вы даже не можете использовать "небезопасный" код для преобразования ссылки в целое число:

unsafe int ReferenceToInt(object o)
{
    // Error: cannot declare a pointer to a managed type.
    fixed (object* ptr = o)
        return (int)ptr;
}

В любом случае, это не будет хорошей идеей, так как компактная сборка мусора может изменить не только адрес каждого объекта, но и относительный порядок между объектами. Даже если GC не изменил относительный порядок, GC может работать в любое время, что сделает заказ по ссылке очень опасным.

Реализация по умолчанию GetHashCode() возвращает какой-то идентификатор объекта, который вы можете использовать вместо этого. И, как упоминал Фредерик, вы можете использовать Object.ReferenceEquals (), чтобы подтвердить, что две ссылки совпадают.

Наконец, в большинстве случаев вы должны просто использовать Dictionary, HashSet или LINQ, как уже упоминали другие.

1 голос
/ 08 ноября 2010

Не прямой ответ на ваш вопрос, а решение вашей реальной проблемы с использованием LINQ:

IEnumerable<Foo> items = new List<Foo>(){ new Foo(), new Foo() };
IEnumerable<Foo> otheritems = items;

bool identical = items.Intersect(otheritems).ToArray().Count() == items.Count();

Это работает путем сравнения ссылок, если только метод Equals не переопределен в типе Foo.

0 голосов
/ 23 марта 2012
...