Почему мне нужно использовать get и set?

У меня есть сегмент кода:

public class MyClass
{
    private string _myProperty;

    public string MyProperty
    {
        get
        {
            return _myProperty;
        }

        set
        {
            _myProperty = value;
        }
    }
}

Какой смысл здесь? Я мог бы объявить строку _myProperty общедоступной, и любой из моих объектов класса сможет напрямую обращаться к ним и получить или установить значение.

Вместо этого мы создаем _myProperty private и используем get и устанавливаем для доступа к ним, используя объект класса.

В любом случае объект класса может получить к ним доступ, и результат всегда будет таким же.

Так зачем использовать этот подход? Это только потому, что я могу реализовать несколько ограничений в сеттер?

Кроме того, какой вред будет вызывать переменные-члены? В этом примере я мог бы раскрыть _myProperty как общедоступный, а не ограничивать его только этим классом, только сделав его закрытым, как предполагал ООП.

Ответ 1

Нет, результат не всегда один и тот же.

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

Прочтите статью которую я написал об этом некоторое время назад.

Обратите внимание, что с С# 2 ваш код может быть намного короче, хотя:

public class MyClass
{
    public string MyProperty { get; set; }
}

Ответ 2

Поле _myProperty представляет собой деталь реализации - он сообщает компилятору, что вы хотите, чтобы какое-то хранилище для ссылки на строку и присвоило ему это имя. Методы get/set являются частью свойства объекта, который абстрагирует как свойство MyProperty. Итак, скажем, если вы хотите изменить способ сохранения/получения строки, сторонние иждивенцы не должны повторно компилировать.

Вы также можете использовать для этого автоматические свойства:

public string MyProperty {get; set;}

Ответ 3

Если вы просто объявляете переменные как общедоступные, на самом деле они не являются правильными. Многие функции, которые используют отражение, не будут работать, в частности DataBinding, Serialization и т.д.

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

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

Ответ 4

Как вы сказали, основной причиной свойств является проверка. Каждый класс несет ответственность за сохранение своих мемберов, а _myProperty является членом MyClass. Путь .Net для реализации этой ответственности - протей. в Java вы должны определить два метода: SetMyPropety и GetMyProperty.

Ответ 5

Важно отметить, что, хотя часто бывает полезно, чтобы классы обертывали поля в свойствах, для структур часто контрпродуктивно это делать. Многие из рекомендуемых ограничений на использование структур связаны с предположением о том, что все структурные поля будут обернуты свойствами. Если семантика структуры предусматривает, что:

  • Его состояние полностью определяется фиксированным числом параметров, все из которых публично открыты для чтения.
  • Этим параметрам может быть свободно назначена любая комбинация значений, которые являются законными для их соответствующих типов.
  • Экземпляр структуры по умолчанию указывается как имеющий все параметры, инициализированные значениями по умолчанию для их соответствующих типов.

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

  1. выполнить быстрее
  2. выразить свое намерение более четко
  3. определили семантику в многопоточных сценариях, где семантика в противном случае была бы темной
Я не вижу большой пользы для того, чтобы потребители такого типа работали медленнее, были написаны неловко и имели мутную многопоточную семантику.

Обратите внимание, что если существует политика против наличия структур с свойствами, которые мутируют 'this', а не политики инкапсуляции всех структурных полей, тогда оператор вроде:

myListOfPoint[4].X = 5;

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

myArraySegment[3] = 9;

который понимается как обращение к массиву, к которому myArraySegment содержит ссылку).