Инкапсуляция данных в C # с использованием свойств - PullRequest
6 голосов
/ 18 сентября 2010

В настоящее время я думаю о инкапсуляции данных в C #, и я немного запутался.Несколько лет назад, когда я начал изучать программирование на C ++, мой профессор сказал мне: - «Создайте класс и спрячьте его члены-данные, чтобы им нельзя было манипулировать напрямую извне»

Пример: вы анализируетеXML-файл и хранить проанализированные данные в некоторых элементах данных внутри класса анализатора.

Теперь, когда я смотрю на C #.У вас есть свойства.Эта функция делает внутреннее состояние / внутренние данные класса видимыми снаружи.Там нет инкапсуляции больше.Правильно?

private string _mystring;
public string MyString
{
  get {return _mystring;}
  set {_mystring = value;}
}

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

Может кто-нибудь объяснить мне это, пожалуйста?

Спасибо

Ответы [ 7 ]

15 голосов
/ 18 сентября 2010

Личные данные инкапсулируются самим свойством. Единственный способ получить доступ к данным - через свойство.

В вашей ситуации выше, есть небольшая причина для использования собственности. Однако, если вам позже понадобится добавить некоторую проверку, вы можете, не нарушая API, т.е. ::

private string _mystring;
public string MyString
{
  get {return _mystring;}
  set 
  {
      if (IsAcceptableInput(value))
         _mystring = value;
  }
}

Помните, что свойство в .NET на самом деле является более чистым синтаксисом для двух методов - одного метода для секции get свойства и одного для секции набора свойств. Он обеспечивает ту же инкапсуляцию, что и пара методов в C ++, но (возможно) более приятный синтаксис для использования.

2 голосов
/ 18 сентября 2010

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

private string _mystring;
public string MyString
{
  get {return _mystring;}
}

Или, как упомянуто Ридом, ваш метод set может выполнять преобразование или проверку любой степени сложности.Например, что-то вроде

private long myPrime;
public long Prime {
   get { return myPrime; }
   set { 
     if (prime(value) {
        myPrime = prime;
     }
     else {
        //throw an error or do nothing
     }
   }
}

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

1 голос
/ 18 сентября 2010

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

1 голос
/ 18 сентября 2010

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

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

Вместо того, чтобы просто сделать свойство общедоступным, тем самым обеспечивая публичный доступ без какой-либо проверки, вы можете использовать методы получения и установки свойствC #:

class StickShiftCar : Car
{
    public int MilesPerHour
    {
        get {return this._milesPerHour;}

        set 
        {
          if (vaule < 20)
              this._gearPosition = 1;
          else if (value > 30)
              this._gearPosition = 2;
          ...
          ...
          this._milesPerHour = value;
  }
}

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

1 голос
/ 18 сентября 2010

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

0 голосов
/ 18 февраля 2018

Самая первая попытка использования свойства для инкапсуляции значения - это get; set;Но C # предоставляет более продвинутую функцию для обогащения функций внутри get и делает свойство доступным только для чтения, только для записи или с определенными условиями.Например, установить значение как

private string temp;
public string temp
{
  get 
    {
       return temp;
    }
}

будет лучше, чем использовать:

public readonly string Temp;
0 голосов
/ 18 сентября 2010

Глядя немного глубже, почему ваш профессор сказал вам заключить в капсулу? Просто потому, что это правильный объектно-ориентированный дизайн? Почему это правильный путь? Языки программирования и парадигмы - это просто способ справиться со сложностью заставить процессор выполнять наш код понятным образом. Есть два читателя кода, машина и люди. Машина с удовольствием загрузит данные с любого адреса в области памяти или ответвится к нему. Мы, люди, с другой стороны, любим думать о «вещах». Наш мозг имеет дело с «вещами», которые имеют атрибуты или которые выполняют действия. Лев съест тебя, копье может защитить тебя, лев пушистый, копье острое. Таким образом, мы можем понимать программы, если они моделируются как «вещи». Свойства должны моделировать атрибуты вещи, а методы должны моделировать действия вещи. На практике это может стать довольно размытым, и все не может быть смоделировано как действие в реальном мире, но усилие сделать это, если все сделано правильно, может сделать программу понятной.

...