Зачем мне частное поле, доступное через публичную собственность? - PullRequest
2 голосов
/ 28 января 2010

Я в основном из мира Java. Итак, свойства C # выглядят неплохо.

Я знаю, что с C # 3.0 или выше я могу использовать автоматические свойства. Мне нравится еще больше:).

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

   private int age;

   public int Age {

     get { return age; }
     set { age = value; }     
   }

Зачем мне возраст частного поля? Что я на самом деле скрываю здесь?

EDIT:

Я полностью понимаю необходимость использования геттера и сеттера. Я упомянул, что я из мира Java и делаю это все время.

Я понимаю, что автоматические свойства в C # 3.0 или выше являются синтетическим сахаром. Но, возможно, мой вопрос имеет более простой ответ. Означает ли это, что (ниже C # 3.0) свойство не имеет никакого значения. Таким образом, он должен получить значение из какого-то другого поля?

Ответы [ 11 ]

3 голосов
/ 28 января 2010

В более старых версиях C # не было автоматических свойств, поэтому вы должны были объявить переменные, на которые действовали свойства, как в вашем примере. В наши дни тот же код может быть выражен как:

public int Age { get; set; }

Я думаю, что это отвечает на ваш вопрос. Однако, если вы спрашиваете «почему бы просто не использовать public int Age; и позволить программистам устанавливать значение в поле напрямую?», Тогда:

Первое, что нужно иметь в виду, это то, что методы доступа к свойствам компилируются в методы. Это означает, что он отличается от ABI простым чтением / записью в переменную члена класса, даже если он синтаксически выглядит так же, как если бы вы имели:

class Fu {
  public int Age;
}

Итак, это означает, что если в какой-то момент в будущем вам нужно добавить какое-либо уведомление об изменении поля Age - если вы используете свойства, вы можете легко добавить эту логику уведомления в установщик свойств без ломая ABI.

public int Age {
  get { return age; }
  set { age = value; NotifySomeOtherCode (); }
}

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

Надеюсь, я понимаю ...

2 голосов
/ 28 января 2010

Автоматические свойства не поддерживались в более старых версиях компилятора C #.

Приведенный выше код более или менее эквивалентен этому (при условии, что поле фактически никогда не используется напрямую):

public int Age {
  get;
  set;
}
1 голос
/ 28 января 2010

Ответ стандартного болота будет «инкапсулировать детали реализации того, как и где хранится возраст».

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

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

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

1 голос
/ 28 января 2010

Автоматические свойства в C # при компиляции заканчиваются функционально точно так же, как приведенный выше код. Компилятор создает для вас вспомогательное поле.

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

1 голос
/ 28 января 2010

В этом случае вам это не нужно. Однако, если вам когда-либо понадобится что-то еще в установщике или получателе, автоматическое свойство не будет работать - вам понадобится личное поле для манипуляции.

0 голосов
/ 28 января 2010

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

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

0 голосов
/ 28 января 2010

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

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

   public int Age {

     get { return age; }
     set { 
          if ( age != value) {
              age = value; 
              OnAgeChanged();
          }
      }     
   }

Вы можете сделать это с помощью свойства и не нарушать код клиента. Поле не имеет этого преимущества.

0 голосов
/ 28 января 2010

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

0 голосов
/ 28 января 2010

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

   private int age;

   public int Age {

     get { return age; }
     set { 
       age = value; 
       Log("value of age changed");
     }     
   }

В открытом поле age вы должны были регистрировать это везде в коде, где вы меняете значение age.

0 голосов
/ 28 января 2010

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

Но в этом нет ничего плохого.За исключением того, что соглашение становится все больше, чтобы называть частное вспомогательное поле "_age".

(я полагаю, вы знаете, почему вы хотите иметь свойство , автоматическое или нет, вместоpublic field . Причина в том, что объект имеет другую подпись, если вы изменяете открытое поле формы на public property, поэтому безопаснее всего начинать со свойства, даже если нет дополнительной логики.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...