19

我最近遇到了一个接口,它只定义了一个像这样的 setter:

public interface IAggregationView
{
   DataTable SetSiteData { set; }
}

我对此进行了查询,相信这是微软提倡的WebPart设计(针对SharePoint)的做法之一。事实上,这个例子是直接从他们的例子中复制而来的。

我认为这是一个不好的模式,我不明白为什么有人应该能够设置一个值,然后不能再次读取它,我相信一个 setter 应该总是伴随着一个 getter(但不一定是其他方式)。

我想知道是否有人可以解释只有一个二传手的好处,为什么微软可能会在这种情况下建议它,以及它是否真的是一个值得遵循的好模式?

4

5 回答 5

22

有两种情况我可以看到这可能是合理的:

  1. 无法获取值例如密码;但是,我个人会用一种void SetPassword(string)方法代替它
  2. 它设计的 API不需要读取该值,并且纯粹是为了公开所需的最低 API

关于我的第一点,如果使用 API 本质上是一个为属性分配值的自动映射器,则该Set... 方法可能并不理想;在那种情况下,属性确实更可取。

关于您的“我不明白为什么有人应该能够设置一个值,然后就无法再次读取它”-但是,在同一点上,可以争辩说设置该值的人已经知道该值(他们设置它),所以他们没有要求这样做。

但是,是的; 拥有一个仅设置的属性是非常不寻常的。

于 2012-09-17T08:58:00.717 回答
15

get和在接口属性中的作用与set类中的作用略有不同。

public interface IAggregationView
{
   DataTable SetSiteData { set; }
}

class AggregationViewImp : IAggregationView
{
   public DataTable SetSiteData { get; set; }  // perfectly OK
}

该接口指定该属性至少应该有一个公共设置器。getter 的定义和可访问性留给实现类。

所以如果接口合约只需要写,get可以保持打开状态。无需要求公共吸气剂。

因此,您也不能真正在接口中指定只读属性。只有“至少读取权限”。

interface IFoo
{
    int Id { get;  }
}

class Foo : IFoo
{
    public int Id { get; set; }  // protected/private set is OK too
}
于 2012-09-17T09:16:32.360 回答
5

我可以想象将它用于(手动)依赖注入。一个类可能需要注入一个仅在内部使用的协作者。当然,通常会选择在类的构造函数中执行此操作,但有时可能希望在运行时更改协作者。

于 2012-09-17T11:49:50.103 回答
2

实现该接口的类可以添加一个 getter。该属性的大多数使用可能是通过实现类,而不是通过接口本身。在这种情况下,大多数代码都可以获取和设置属性。接口的唯一原因可能是有一些通用代码访问一个类族的方法/属性的公共子集。该代码只需要设置器,而不需要获取器。界面记录了这一事实。

接口只是声明一组“原子需要”操作的工具(例如,如果您需要调用方法 A,则需要读取属性 B 并设置属性 C)。

与往常一样,这取决于.

于 2012-09-17T09:03:48.490 回答
1

根据我的经验,此类接口的出现是由于某些特殊需要,而不是出于架构原因。例如,在 ASP.NET 应用程序中,当人们想要维护全局状态时,有时会从这样的接口派生 Global.asax 生成的类型。有人可能会在应用程序的单独部分创建初始化值,并需要将其发布到全局位置。

我通常喜欢用一个SetXxx方法替换一个只设置的属性,并让该方法检查它最多被调用一次。这样我就清楚地执行了“初始化风格”,它的气味要少得多(恕我直言)。

当然,一个人不能设置永远不会产生这样的东西,但它是应该避免的,并且肯定会在代码审查期间提出问题。

于 2012-09-17T08:55:25.697 回答