Свойство или метод WriteOnly? - PullRequest
       19

Свойство или метод WriteOnly?

8 голосов
/ 27 ноября 2008

Есть ли конкретный сценарий, в котором свойство WriteOnly имеет больше смысла, чем метод? Методный подход кажется мне гораздо более естественным.

Каков правильный подход?

Использование свойств :

Public WriteOnly Property MyProperty As String
   Set(ByVal value as String)
      m_myField = value
   End Set
End Property
public string MyProperty
{
   set{ m_myField = value;}
}

Использование методов :

Public Sub SetMyProperty(ByVal value as String)
   m_myField = value
End Sub
public void SetMyProperty(string value)
{
   m_myField = value;
}

EDIT Просто чтобы уточнить, я имею в виду свойства «WriteOnly».

Ответы [ 8 ]

11 голосов
/ 27 ноября 2008

Как ни крути, руководящие принципы разработки Microsoft Framework (как воплощено в их инструменте FxCop) не допускают свойств, доступных только для записи, и отмечают их наличие как проблему разработки API из-за неинтуитивности такого подхода.

11 голосов
/ 27 ноября 2008

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

В качестве примера: установка списка значений в раскрывающемся меню и доступ к выбранному элементу:

public interface IWidgetSelector
{
  void SetAvailableWidgets(string[] widgets);

  string SelectedWidget { get; set; }
}

Имеет больше смысла, чем:

public interface IWidgetSelector
{
  string[] AvailableWidgets { set; }

  string SelectedWidget { get; set; }
}
4 голосов
/ 25 февраля 2010

Вот пример кода, который я использовал в проекте XNA. Как видите, Scale предназначен только для записи, он полезен и (разумно) интуитивно понятен, а свойство чтения ( get ) не имеет смысла. Конечно, его можно заменить методом, но мне нравится синтаксис.

public class MyGraphicalObject
      {
      public double ScaleX { get; set; }
      public double ScaleY { get; set; }
      public double ScaleZ { get; set; }

      public double Scale { set { ScaleX = ScaleY = ScaleZ = value; } }

      // more...
      }
3 голосов
/ 27 ноября 2008

Просто еще одна мысль:
Предполагается, что свойство ощущается и испытывается так же, как поле . Невозможно создать поле с именем WriteOnly. ReadWrite возможен, ReadOnly (const) возможен, но не WriteOnly. Несоответствие - это плохо [тм]

2 голосов
/ 27 ноября 2008

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

1 голос
/ 27 ноября 2008

Я сомневаюсь, что есть правильный выбор. Это вопрос вкуса.

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

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

public string Password { set; }

Если ваш сет влияет на несколько участников, я бы пошел с методом. Что-то вроде:

public void SetToRunMode(object[] runvars);

Самое важное - это последовательность.

0 голосов
/ 26 июля 2010

Согласно правилу анализа кода CA1044:

Get-аксессоры предоставляют доступ для чтения к свойству, а set-аксессоры предоставляют доступ для записи.

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

добавить метод доступа get к свойству.

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

Пожалуйста, обратитесь http://msdn.microsoft.com/en-us/library/ms182165.aspx для более подробной информации

0 голосов
/ 27 ноября 2008

Однако я видел, что сама .Net Framework использует свойства ReadOnly, первое, что приходит на ум:

System.Net.Mail.MailMessage.To

Для которого вы должны вызвать метод для записи:

System.Net.Mail.MailMessage.To.Add(Recipient As String)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...