неизменные свойства объекта в C # - PullRequest
1 голос
/ 26 августа 2009

Я ищу способ сортировки списка объектов (любого возможного типа), чтобы что бы ни происходило с объектами, пока они не уничтожены, порядок остается неизменным (поэтому hashCode не хорошая идея, потому что в некоторых классах она меняется с течением времени), по этой причине я думал использовать адрес объекта в памяти, но я не уверен, что это всегда остается неизменным (Может ли адрес меняться мусором собирать звонок например?). Однако я ищу свойства объектов (любого типа), которые будут оставаться неизменными до тех пор, пока объект не будет уничтожен. Есть ли кто-нибудь из них? И если да, то что они?

Ответы [ 3 ]

2 голосов
/ 26 августа 2009

Да, объекты могут перемещаться в памяти сборщиком мусора, если вы специально не попросите об этом (и, как правило, рекомендуется, чтобы GC сделал свое дело).

Здесь вам понадобится дополнительная таблица: создайте словарь с ключевыми объектами, а в качестве значения укажите все, что вам нравится (это может быть оригинальный хеш-код объекта или даже случайное число). Когда вы сортируете, сортируйте по этой боковой клавише. Теперь, если, например, объект a имеет значение «1» в этом словаре, он всегда будет отсортирован первым - независимо от того, какие изменения внесены в a, потому что вы будете искать в боковом словаре ключ и код для не знает, пойти ли туда и изменить его (и, конечно, вы стараетесь сохранить эти данные неизменными). Вы можете использовать слабые ссылки , чтобы убедиться, что ваши словарные записи исчезнут, если нет другой ссылки на объект a.

1 голос
/ 26 августа 2009

Обновлено с учетом детализации, добавленной к вопросу (комментарии); просто возьмите копию содержимого списка, прежде чем сортировать его ...


Нет, адрес не является фиксированным. А для произвольных объектов нет разумного способа сделать это. Для ваших собственных объектов вы можете добавить что-то общее, например:

interface ISequence { int Order { get; } }
static class Sequence {
    private static int next;
    public static int Next() {
        return Interlocked.Increment(ref next); }
}
class Foo : ISequence {
    private readonly int sequence;
    int ISequence.Order { get { return sequence; } }
    public Foo() {
        sequence = Sequence.Next();
    }
}

Немного неаккуратно, но оно должно работать и может использоваться в базовом классе. Order теперь является неизменным и последовательным. Но только AppDomain -специфичный, и не все API-интерфейсы сериализации будут уважать его (в таких случаях вам потребуется использовать обратные вызовы сериализации для инициализации последовательности).

0 голосов
/ 26 августа 2009

Сортировка по адресу памяти возможна только по эталонным объектам. Так что не все типы можно сортировать таким образом, а примитивные типы и структуры - нет.

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

public interface ISortable
{
  Guid SortId { get; }
}

class Foo : ISortable
{
  Foo()
  {
    SortId = Guid.NewGuid();
  }
  Guid SortId { get; private set; }
}

Преимущество guid в том, что его можно создавать независимо в каждом классе. Вам не нужна синхронизация, вы просто присваиваете каждому классу идентификатор.

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


Редактировать: Вы можете написать свой специализированный список, который может хранить заказы.

Либо вы сохраняете исходный порядок при создании списка из другого списка, а затем вы можете восстановить порядок в любой момент времени. Новые предметы могут быть поставлены в конце. (есть новинки в любом случае?)

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

Еще лучше было бы поместить эту логику в класс сортировки. Так что это работает для каждого списка, который был отсортирован вашим классом сортировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...