0

在A类中(如果列表不为空,将输出什么):

private List<int> _myList = new List<int>
public List<int> MyList {get{return _myList;} set{_myList = value;}}

B类:

public bool MyClassBMethod(stuff)
{
     //stuff
     try{
          something
     }
     catch(Exception){
         ClassA.MyList.Add(stuff);
         return false;
     }
     return true;
}

像这样编辑列表是不好的做法吗?或者没关系?

编辑:我只在我的方法需要返回其他内容(布尔、对象、字符串等)时才添加到列表中。

4

5 回答 5

2

你通常不应该那样做。

您向类的客户端公开了一个非常大的接口,因此很难测试您的类是否在所有情况下都有效。如果有人在您不期望的情况下删除了值会发生什么?或者,如果他们添加了超出范围的值怎么办?您无法在他们调用您的方法时对其进行验证List,因此您的类可能会在稍后的某个时间点突然中断,此时可能难以追踪不良数据的来源。

最好Add在你的类上有一个调用列表的方法Add,并保持列表私有。然后你可以控制你的客户做什么,只公开他们需要使用的功能(并且你已经测试过)。

于 2012-05-22T20:43:43.820 回答
2

一般来说,一个类应该负责管理它自己的内部状态。通过向这样的成员提供完全的公共访问权限,您基本上是在说 A 类正在放弃对其状态部分的责任。它不能对 _myList 包含的内容做出假设,因为任何人都可以随时更改它。

好不好取决于你的意图是什么,但它肯定与解耦和封装的想法背道而驰。同样,是否解耦和封装取决于您。

一个更好的问题是确定 A 类和 B 类之间的哪种解耦对您的设计最有利,然后您就可以决定要公开哪些成员以及如何公开。

于 2012-05-22T20:47:31.557 回答
0

这是一种很常见的做法。不那么常见的是公开设置。将其设为私有,在 A 构造函数上初始化列表,一切就绪。

public ObservableCollection<int> MyPublicList {get; private set;}

WPF 充满了像这样的声明。

于 2012-05-22T20:43:35.433 回答
0

一如既往,这取决于。如果打算在类之外编辑列表(它是该类接口的一部分)并且允许所有常规列表操作,则可以。如果只允许操作的子集,那么您不应该像这样使用它 - 使用自定义列表(或列表周围的包装器)来强制执行所有约束。例如,如果列表在类外必须是只读的,那么您可以在类外提供ReadOnlyCollection包装器。这一切都归结为强制数据完整性。

于 2012-05-22T20:49:08.507 回答
0

这取决于您是否关心列表是否公开。通过公开和访问公共的、具体的类型,您正在公开实现细节并增加类与其消费者之间的耦合。你也限制ClassA了 's 强制数据一致性的机会,因为它的实现细节不再被正确封装。

有时,这是完全可以接受的,有时则不是。

我会说在对象模型愚蠢的情况下这是可以接受的。愚蠢,我的意思是它只包含数据。在将 JSON/XML 解析为对象时经常会发生这种情况——事物的结构是为了反映数据,而行为并不重要,因为它很少。如果您只是在一个小的代码库中破解和/或更改的范围有限,或者涉及的行为很少,那么它也更容易接受。

不过,我通常会避免它。

首先,假设您添加到ClassA列表中的项目必须是素数。如果您编写一个AddItem()方法,您可以轻松地执行此检查,但如果列表公开,则很难有效地执行此检查。

其次,假设您决定将列表更改为字典。您现在可能会破坏调用代码站点(ClassB用于一个),因为它们以前依赖于ClassA. 相反,如果您创建了名为AddItem()andRemoveItem()或类似的方法ClassAClassB则不会关心内部实现是 Set、Dictionary 还是 List 等,也不会在进行更改时中断。

围绕“点入事物”(如blah.List[3].GetProduct(3).Reviews.First())的准则有一个名称:得墨忒耳法则

得墨忒耳法则的重点是:

基本概念是给定对象应尽可能少地假设其他任何事物(包括其子组件)的结构或属性。

您经常需要编写更多代码,但它可以防止更改。

于 2012-05-22T20:53:15.187 回答