Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic 我应该使用像IEnumerable这样的接口,还是像List这样的具体类<&燃气轮机;_Language Agnostic_Oop_Polymorphism - Fatal编程技术网

Language agnostic 我应该使用像IEnumerable这样的接口,还是像List这样的具体类<&燃气轮机;

Language agnostic 我应该使用像IEnumerable这样的接口,还是像List这样的具体类<&燃气轮机;,language-agnostic,oop,polymorphism,Language Agnostic,Oop,Polymorphism,我最近在其他地方表达了我的观点*,但我认为它值得进一步分析,所以我将其作为自己的问题发布 假设我需要在程序中创建并传递一个容器。我可能对一种容器和另一种容器没有强烈的意见,至少在这个阶段,但我确实选择了一种;为了便于讨论,假设我将使用一个列表 问题是:编写我的方法来接受和返回高级接口(如C#的IEnumerable)是否更好?或者我应该编写方法来获取并传递我选择的特定容器类。 我应该寻找哪些因素和标准来决定?什么样的项目能从中受益?计算机语言会影响你的决定吗?演出程序大小?个人风格 (这有关系吗

我最近在其他地方表达了我的观点*,但我认为它值得进一步分析,所以我将其作为自己的问题发布

假设我需要在程序中创建并传递一个容器。我可能对一种容器和另一种容器没有强烈的意见,至少在这个阶段,但我确实选择了一种;为了便于讨论,假设我将使用一个列表

问题是:编写我的方法来接受和返回高级接口(如C#的IEnumerable)是否更好?或者我应该编写方法来获取并传递我选择的特定容器类。

我应该寻找哪些因素和标准来决定?什么样的项目能从中受益?计算机语言会影响你的决定吗?演出程序大小?个人风格

(这有关系吗?)


**(家庭作业:找到它。但是在你寻找我自己的答案之前,请在这里张贴你的答案,以免使你产生偏见。)*

唯一影响你决定的是你计划如何使用参数。如果您只是对其进行迭代,请使用
IEnumerable
。如果您正在访问索引成员(例如
var x=list[3]
)或以任何方式修改列表(例如
list.Add(x)
),则使用
ICollection
IList
您的方法应始终接受执行其功能所需的最小特定类型。如果您的方法需要枚举,请接受
IEnumerable
。如果它需要做
IList
-特定的事情,根据定义,您必须给它一个
IList

,这确实很重要,但正确的解决方案完全取决于使用情况。如果您只需要执行一个简单的枚举,那么请确保使用IEnumerable,这样您就可以传递任何实现者来访问所需的功能。但是,如果您需要列表功能,并且不希望每次调用该方法时都要创建一个新的列表实例(如果传递的可枚举项不是列表),那么请使用列表。

始终存在折衷。一般的经验法则是尽可能高层次地声明事物。因此,如果您只需要访问IEnumerable中的方法,那么这就是您应该使用的方法

最近的另一个SO问题示例是采用文件名而不是文件*(或文件描述符)的C API。在那里,文件名严格限制了可以传递的内容(有许多内容可以通过文件描述符传递,但只有一个具有文件名)

一旦你必须开始铸造,你要么太高,要么你应该制作第二种方法,采用更具体的类型

我能想到的唯一例外是,当速度是绝对必须的,并且您不想花费虚拟方法调用的费用时。声明特定类型可以消除虚拟函数的开销(这取决于语言/环境/实现,但作为一个一般性的陈述可能是正确的)。

我回答了一个类似的C#问题。我认为你应该尽可能提供最简单的合同,在我看来,在托收的情况下,通常是T的IEnumerable

实现可以由内部BCL类型提供—可以是Set、Collection、List等等—其所需的成员由您的类型公开


抽象类型始终可以继承简单的BCL类型,这些类型由具体类型实现。在我看来,这让你更容易坚持。

正是与我的讨论引发了这个问题,所以我已经知道了我的答案,但答案在这里!:)

我认为LINQtoObjects已经为这个问题提供了一个很好的答案。通过对项目序列使用最简单的接口,它为如何实现该序列提供了最大的灵活性,允许延迟生成,在不牺牲性能的情况下提高生产率(不是真正意义上的)

不成熟的抽象确实会有成本,但主要是发现/发明新抽象的成本。但是,如果已经提供了非常好的,那么不利用它们就太疯狂了,这就是通用集合接口提供给您的

有些人会告诉你,公开一个类中的所有数据“更容易”,以防你需要访问它。同样,Euro建议最好使用一个丰富的容器接口,比如
IList
(或者甚至是具体的类
List
),然后稍后再清理

但是我认为,正如最好隐藏不想访问的类的数据成员,以便以后可以轻松地修改该类的实现,因此应该使用最简单的接口来引用一系列项。在实践中,从暴露一些简单和基本的东西开始,然后再“放松”它,比从一些松散的东西开始并努力给它强加秩序要容易得多

因此,假设
IEnumerable
可以表示一个序列。然后,在需要
添加
删除
项(但仍然不需要通过索引查找)的情况下,使用
IContainer
,它继承了
IEnumerable
,因此可以与其他代码完美互操作

通过这种方式,将非常清楚(仅从某些代码的本地检查)该代码将能够对数据执行什么操作


的确,小程序需要较少的抽象。但如果他们成功了,他们往往会成为大项目。如果他们首先使用简单的抽象,这就容易多了。

同意,但我正要问几乎完全相同的问题,因为我的代码在使用IEnumerable时感觉很尴尬;而不是List foos=fookquery.GetFoos(