Оценка значения в сеттере даже не проверяется - PullRequest
3 голосов
/ 08 ноября 2010

У меня есть свойство в составном элементе управления, которое проверяет, изменилось ли значение до фактической установки связанного частного поля и выполнения нескольких других действий.

Однако, похоже, что оно никогда не оцениваетоператор.

Вот код свойства:

public T SearchCriteria
        {
            get
            {
                return mySearchCriteria;
            }
            set
            {
                if (value != mySearchCriteria)
                {
                    mySearchCriteria = value;
                    EnsureChildControls();
                    SearchGridParser parser = SearchGridParserFactory.GetParser(this.Type);
                    parser.SetSearchPanelControls<T>(this.mySearchCriteria, ref mySearchParametersPanel);
                    GridView.PageIndex = 0;
                }
            }
        }

Я прошел этот код, и каждый раз, когда он получает значение «=! = mySearchCriteria», он оценивается как ложное и пропускаеткод внутри оператора if.Фактически, он делает это, даже когда я изменяю его на «value == mySearchCriteria» .. если просто полностью пропускает его, независимо от того, как он оценивает!

Что за хей?

попытался изменить порядок аргументов в проверке, а также с помощью object.Equals (), но ни одно из этих изменений не имело никакого значения.

Я переопределил Equals,! =, == и GetHashCode.

В коде есть другие места, где он использует "==" и "! =" Для этих типов объектов без проблем, поэтому я знаю, что мое переопределение работает правильно.

Проблема в том,это никогда не затрагивает переопределенные методы.Я ставлю разрывы на "==", "! =", "Equals" и "GetHashCode", и ни один из них не вызывается при оценке оператора "value! = MySearchCriteria".

Это похоже на этополностью пропускает оценку.

1 Ответ

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

Использование == между универсальными типами почти всегда плохая идея. Операторы перегружены , а не переопределены , поэтому даже если в ваших фактических типах есть оператор ==, компилятор об этом не узнает. (Это означает, что ваше утверждение о том, что вы «переопределили» == и !=, уже неверно - вы перегрузили эти операторы. Вы должны убедиться, что понимаете разницу, поскольку это очень важно.)

Когда вы пишете:

В коде есть другие места, где он использует "==" и "! =" Для этих типов объектов без проблем, поэтому я знаю, что мое переопределение работает правильно.

Я подозреваю, что эти области не в общем коде ... они там, где компилятор знает, какие типы сравниваются, поэтому знает, как использовать ваши перегрузки. Это сильно отличается от вашей общей ситуации, когда компилятор не не знает, что использовать для ==, поэтому возвращается к ссылочной идентичности.

Я предполагаю, что у вас есть общее ограничение where T : class, или ваш код вообще не будет компилироваться - но он все равно просто выполнит сравнение ссылок, вместо того чтобы использовать перегрузку, предоставляемую фактическим типом T .

Используйте EqualityComparer.Default<T>.Equals(value, mySearchCriteria) для использования переопределенных реализаций Equals, включая IEquatable<T>.

...