Можно ли удалить установщик свойств (без ЛЮБОЙ проблемы) в примере, приведенном в вопросе? - PullRequest
3 голосов
/ 20 апреля 2011

В существующем коде моего проекта в ряде мест свойство объявляется так:

public long ResourceID
{
    get
    {
        return this.resourceID;
    }
    set
    {
        if (this.resourceID != value)
        {
            this.resourceID = value;
        }
    }
}

Примечание: private long resourceID уже объявлено.

Свойства не только значениятипы , но также и ссылочные типы (включая строку) тоже объявляются следующим образом.

Другой пример:

public Collection<Ability> Abilities
{
    get
    {
        return this.abilities;
    }
    set
    {
        if (value == null)
        {
            throw new ArgumentNullException("Abilities");
        }
        this.abilities = value;
    }
}

Насколько мне известно, сеттер в первом примере не имеет никакого смысла, и условие if здесь не имеет смысла.Поэтому я решил изменить код (как часть рефакторинга), чтобы сделать их Авто-Свойства.(Во втором примере мне нужен сеттер, так как там обрабатывается исключение.)

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

Примечание. Дайте мне знать, если это чисто домашний вопрос.

Ответы [ 6 ]

4 голосов
/ 20 апреля 2011

Преобразование:

private long resourceID;
public long ResourceID
{
    get
    {
        return this.resourceID;
    }
    set
    {
        this.resourceID = value;
    }
}

в:

public long ResourceID { get; set; }

не причинит никакого вреда, гарантировано.

Удаление оператора if может причинить вред.Например, в WPF при работе с шаблоном MVVM и реализации интерфейса INotifyPropertyChanged часто рекомендуется проверять, изменилось ли значение перед его фактической установкой.Снятие этой проверки вызовет отправку уведомлений в пользовательский интерфейс независимо от того, изменилось ли значение или нет.Так что это будет серьезное изменение.

2 голосов
/ 20 апреля 2011

Я могу думать только об одном типе проблемы, с которой вы можете столкнуться (это можно исправить):

Если вы используете ORM или другой внешний инструмент, они могут полагаться на соглашение об именах для поиска свойств / полей,Таким образом, сторонняя dll может искать поле resourceId, которого больше нет.

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

1 голос
/ 20 апреля 2011

Существует несколько крайних случаев , в которых это может причинить вред:

Изменение на автоматически реализуемое свойство {get;set;}

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

Удаление if теста

будет хорошо для большинства типов данных, таких как long и т. д., однако, если вы используете его с типом, который реализует пользовательскую операцию равенства, вы можете обнаружить, что внезапно меняете ссылку, когда ранее (с if)объекты, о которых сообщается, равны для разных ссылок


Первая - более вероятная проблема.Если вы используете BinaryFormatter, то оставьте приватное поле (возможно, удалите тест if).А затем начните рефакторинг вашего кода от BinaryFormatter; p

0 голосов
/ 20 апреля 2011

Обычно в таких сценариях и как вы объяснили, это не должно быть проблемой.Вы можете просто пойти дальше и изменить код всех свойств;

public long ResourceID { get; set; }

Или

public long ResourceID
{
    get { return this.resourceID; }

    set { this.resourceID = value; }
}
  • Но это может вызвать проблему, если при изменении значения свойства оно каскадно переходит к другому вызову пользовательской функции, который выполняется толькоесли новое значение отличается от старых.Обычно, когда вы реализуете пользовательские события или даже, может быть, в случае событий с измененным свойством
  • Также может повлиять на использование классов контекста данных

Оба сценария полностью зависят от приложения.

Я бы предложил вам реактор с осторожностью.Или, как вы написали сами, HOMEWORK.

0 голосов
/ 20 апреля 2011

Ваш первый пример устанавливает поле resourceID только в том случае, если его значение изменилось.

Единственное отличие, которое вы увидите, удалив тест "if", - это возможное влияние, если значение читают несколько потоков.В этом случае они, вероятно, должны использовать блокировку, поэтому почти наверняка безопасно удалить тест.

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

0 голосов
/ 20 апреля 2011

То, что вы сделали, правильно.Утверждение if не имеет смысла.Я всегда думаю, что чем меньше кода, тем лучше, потому что количество строк кода прямо пропорционально количеству ошибок.

public long ResourceID { get; set; } 
...