Какой смысл делать отдельные публичные функции для получения/установки приватного значения?

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

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

Тем не менее, часто я вижу, что другой код использует частные значения в своем классе, а затем создает отдельные функции для получения и установки значения, например:

private bool fooBar;

public void SetFooBar(bool boolean)
{
   fooBar = boolean;
}

public bool GetFooBar()
{
   return fooBar;
}

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


person Mathue24    schedule 29.05.2019    source источник
comment
В C# вы должны использовать свойства вместо методов Get/Set, но общий смысл заключается в том, чтобы скрыть реализацию того, как значение сохраняется внутри, и упростить внесение некритических изменений.   -  person juharr    schedule 29.05.2019
comment
Как правило, вы не должны создавать поле public, но должны сделать его общедоступным (например, public bool FooBar { get; set; }). Использование методов для получения и установки не характерно для С#.   -  person Rufus L    schedule 29.05.2019


Ответы (2)


  1. Потому что прямое изменение состояния объекта в ООП запрещено.
  2. Потому что вы не можете поместить поля в интерфейс (и как только вы зайдете достаточно далеко, вы обычно получите доступ к большинству других объектов через интерфейсы)
  3. Потому что он допускает дополнительную логику (например, создание событий), когда другой объект хочет взаимодействовать с полем.
  4. Поскольку некоторые вещи (например, привязки WPF) работают только со свойствами, а не с полями.

  5. Поскольку вы можете захотеть изменить способ извлечения/сохранения значения (не только в памяти) позже

(Обратите внимание, что в C# это обычно делается как свойство, а не как метод, например public bool Foo {get; set;})

person BradleyDotNET    schedule 29.05.2019
comment
Спасибо за информацию, в следующий раз сделаю это через свойства. Я где-то читал, что смысл делать это с помощью метода заключался в том, чтобы поле оставалось закрытым, и что вы хотите, чтобы они были закрытыми по соображениям безопасности или что-то в этом роде (?). Тем не менее, если я использую public bool Foo {get; set;}, то я, по сути, делаю его общедоступным полем, верно? - person Mathue24; 29.05.2019
comment
Моя ошибка, я имел в виду, что если я использую public bool Foo {get; set;}, то я делаю его общедоступным, но чем оно отличается от общедоступного поля? - person Mathue24; 29.05.2019
comment
@ Mathue24 Mathue24 На самом деле это не причина безопасности (особенно потому, что к закрытым членам можно получить доступ через отражение, несмотря ни на что), а скорее хорошая причина дизайна. Свойства отличаются от полей в пунктах 2, 3, 4 и 5 моего ответа. Автоматические свойства (то, что я перечислил) различаются в 2 и 4 - person BradleyDotNET; 29.05.2019

Это позволяет изменить способ хранения значения независимо от того, как к нему обращаются внешние пользователи.

Используя функции Getter и Setter, вы можете запрашивать данные из локального кеша или извлекать их из базы данных.

C# поддерживает реализации функций Getter Setter с использованием метода доступа к стилю свойства.

private bool _fooBar
public bool FooBar
{
 get { return _fooBar; }
 set {  _fooBar = value; }
}

Как упоминалось в комментариях BradleyDotNET, вы можете написать их так, чтобы напоминает лямбда-выражения, начиная с C# 7.0

private bool _fooBar
public bool FooBar
{
    get => _fooBar;
    set => _fooBar = value;
}

Как упоминалось в BradleyDotNET, вы можете написать эту точную реализацию как

public bool FooBar { get; set; }

Который будет действовать так же.

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

public bool FooBar { get; protected set; }
person BenVlodgi    schedule 29.05.2019
comment
А в C# 7 get может быть get => _fooBar - person BradleyDotNET; 29.05.2019