只写属性还是方法?

8

有没有某种情况,写入属性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;
}

编辑 为了明确一点,我指的是“只写”属性。

8个回答

11

就它的价值而言,微软框架设计指南(如其FxCop工具所体现)不鼓励使用只写属性,并将其存在视为API设计问题,因为这种方法的不直观性。


11

我认为属性是指可以设置只读或读/写的内容。 写入属性的行为不明显,因此我避免创建它们。

以一个例子来说,在视图上设置下拉列表中的值并访问所选项目:

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

  string SelectedWidget { get; set; }
}
比起这样说更有意义:
public interface IWidgetSelector
{
  string[] AvailableWidgets { set; }

  string SelectedWidget { get; set; }
}

4

这里是我在一个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

另一个想法:
属性应该与字段感觉和味道相同。您无法创建WriteOnly的字段。 ReadWrite是可能的,ReadOnly(const)是可能的,但不是WriteOnly。不一致性是不好的[tm]


2

我同意你的直觉:使用方法。从一些答案中可以看出,只写属性的概念有点奇怪。SetInternalDataProperty() 更易于理解,最终,这是一个哪种方法会导致最少混淆的问题。我会听从你的直觉。


1

我认为没有绝对正确的选择,这只是个人口味问题。

在两种情况下,都会失去一些封装性。使用该方法或属性的开发人员需要了解一些内部实现才能理解结果。因此,我会尽可能避免使用它们,否则只会适度使用。

对我来说,属性意味着与私有成员有密切联系,并可能具有访问规则。如果您只是设置一个安全的私有成员,我会使用属性:

public string Password { set; }

如果你的设置影响到多个成员,我会选择使用方法。类似这样:
public void SetToRunMode(object[] runvars);

最重要的是一致性。


0
根据代码分析规则CA1044:
获取访问器提供对属性的读取访问,设置访问器提供写入访问。
设计指南禁止使用只写属性。这是因为允许用户设置值,然后防止用户查看该值不提供任何安全性。此外,没有读取访问权限,无法查看共享对象的状态,这限制了它们的实用性。
向属性添加一个获取访问器。
或者,如果需要只写属性的行为,请考虑将此属性转换为方法。
有关更多详细信息,请参见http://msdn.microsoft.com/en-us/library/ms182165.aspx

0

然而,我曾经看到过 .Net Framework 自身使用 ReadOnly 属性,首先想到的是:

System.Net.Mail.MailMessage.To

你需要调用一个方法来写入:
System.Net.Mail.MailMessage.To.Add(Recipient As String)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接