Пожалуйста, объясните методику, используемую в этом коде для проверки равенства и идентичности объектов. - PullRequest
4 голосов
/ 04 ноября 2011

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

Лучше, если вы можете предоставить мне любую веб-ссылку / книжную ссылку для подробного обсуждения.

[Serializable]
    public abstract class BusinessObject<T> : IBusinessObject where T : BusinessObject<T>
    {
        private int? requestedHashCode;

        public virtual int ID { get; set; }

        public virtual bool Equals(IBusinessObject other)
        {
            if (null == other || !GetType().IsInstanceOfType(other))
            {
                return false;
            }
            if (ReferenceEquals(this, other))
            {
                return true;
            }

            bool otherIsTransient = Equals(other.ID, default(T));
            bool thisIsTransient = IsTransient();
            if (otherIsTransient && thisIsTransient)
            {
                return ReferenceEquals(other, this);
            }

            return other.ID.Equals(ID);
        }

        protected bool IsTransient()
        {
            return Equals(ID, default(T));
        }

        public override bool Equals(object obj)
        {
            var that = obj as IBusinessObject;
            return Equals(that);
        }

        public override int GetHashCode()
        {
            if (!requestedHashCode.HasValue)
            {
                requestedHashCode = IsTransient() ? base.GetHashCode() : ID.GetHashCode();
            }
            return requestedHashCode.Value;
        }
}

Что такое временный объект?

Ответы [ 2 ]

3 голосов
/ 04 ноября 2011
  • сначала проверяется, является ли other экземпляром того же типа, что и текущий объект.Если нет, они не равны
  • , затем выполняется равенство ссылок, чтобы проверить, являются ли other и текущий объект одним и тем же экземпляром.Если они, очевидно, они равны
  • Если и other, и текущий объект являются временными (т.е. еще не сохранены), у них нет идентификатора, поэтому их нельзя сравнивать по идентификатору.Вместо этого они сравниваются по ссылке. (как отметил Марк Грэвелл в комментариях, тест, чтобы проверить, является ли объект временным, сломан; не имеет смысла сравнивать int со значением по умолчанию (T))В конце концов, их идентификаторы сравниваются;объекты считаются равными, если они имеют одинаковый идентификатор
2 голосов
/ 04 ноября 2011

Я думаю , что код пытается сделать, это сказать "есть ли у него еще идентификатор", то есть "временный" объект может (если я правильно прочитал намерения кода) быть тем, который не являетсяпока что сохраняется в БД.Тогда равенство определяется как:

  • , если оно имеет идентификатор, соответствует ли оно?(даже для разных экземпляров одного и того же типа)
  • если у него нет идентификатора, это один и тот же экземпляр объекта (ссылка)

к сожалению, реализация выглядит совершенно неработающей,поскольку Equals(ID, default(T)) не имеет смысла, когда T является чем-то совершенно другим (a BusinessObject<T>) - следовательно, default(T) всегда будет null, а ID будет никогда будет null (этоне обнуляется).Так что ничто никогда не будет сообщать о переходных процессах.

Кроме того, этот код:

if (null == other || !GetType().IsInstanceOfType(other))

является чрезвычайно неэффективным.Я подозреваю, что что-то, связанное с as, было бы гораздо предпочтительнее, но опять-таки: код выглядит настолько ... замученным ... что мне не хочется переоценивать намерения.

...