返回 IList; 与 C# 中的数组相比?
我最近问某人为什么他更喜欢返回强类型数组而不是 IList。 我一直认为,面对生命周期较长的项目,针对接口编程是最灵活、最好的编程方式。 所以当他回答时我感到很奇怪:
我们通常更喜欢不可变类型 超过可变的。 数组是 不可变的。 IList 不是。
我不完全确定我理解这个陈述。 谁能帮忙澄清一下吗?
感谢你们提供的任何帮助。
I was recently asking someone why he preferred to return a strongly-typed array over an IList. I had always thought that programming against an interface was the most flexible and best way program when faced with a project having a long life. So it struck me as odd when he replied:
We typically prefer immutable types
over mutable ones. Arrays are
immutable. IList is not.
I'm not entirely sure I understand this statement. Can anyone help clarify this?
Thanks for any help you guys can provide.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
也许他的意思是数组的大小是“不可变的”?
基本上,只要声明一次大小,就只能使用它。 对于列表,您始终可以使用“添加”。
我假设,如果您确定列表的大小,也许数组更快一点?
Perhaps he meant the size of the array as "immutable"?
Basically, you declare the size once and you're stuck with it. With lists, you can always use "Add".
I suppose that if you're sure about the size of the list, perhaps array is a bit faster?
出色地。 IList 是可变的,因为您可以添加和删除项目,而不仅仅是更改已存在的项目。 数组可以让你搞乱单个项目,但特定的索引永远不会完全无效。 选择不变性的原因有很多——例如,它使意外数据损坏的表面积变得更小。
Well. IList is mutable in the sense that you can add and remove items, rather than just change the items that are already there. An array lets you mess with individual items, but a particular index will never become entirely invalid. There's any number of reasons to prefer immutability -- it makes the surface area for accidental data corruption much smaller, for example.
无论“他”是谁,在这个话题上都是100%错误的。 数组是非常可变的。 这实际上是不返回数组的原因之一。 没有办法阻止调用者将数组的元素更改为他们想要的任何内容。
数组不可变的唯一方式是它的长度。 一旦分配了数组,它的长度就不能更改。 即使像 Array.Resize 这样的 API 实际上也不会调整数组的大小,它们只是分配一个新数组,复制内容并返回新数组(在本例中通过引用)。
不过,我确实同意,在很多情况下,最好返回不可变数据。 第一个是它允许您返回对类的内部集合的引用,而无需执行完整的复制,同时防止调用者弄乱您的内部状态。 大多数可变集合无法做出这样的保证。
Whoever "he" is, is in 100% wrong on the topic. Arrays are a very much mutable. This is in fact one of the reasons not to return an array. There is no way to prevent a caller from changing the elements of an array to whatever they please.
The only way in which an Arrray is immutable is in it's length. Once an array is allocated, it's length cannot be changed. Even APIs such as Array.Resize don't actually resize the array, they just allocate a new one, copy the contents and return the new array (by reference in this case).
I do agree however that there are many cases in which it is better to return immutable data. The primary one is that it allows you to return a reference to an internal collection of a class without doing a complete copy and at the same time preventing the caller from messing with your internal state. Most mutable collections cannot make such guarantees.
我认为他可能认为既然数组的长度属性是不可变的,那么不知何故数组比 IList 更不可变,或者他可能使用了错误的词并将具体与不可变互换。 谁知道呢,但这是一个奇怪的答案。
我认为返回一个列表有一些暗示,可以修改它,或者它可能会改变,而返回一个数组并不意味着那么多。
例如,如果您在存储库顶部有一个对象模型,并且有一个像 GetCars() 这样返回列表的方法,并且初级程序员看到 cars.Add(Car c) ...您会认为他完全疯了cars.Add(new Car()) 实际上可能会在存储库中添加一辆车? 数组本质上更加明确。
我认为 List 在属性中使用更合适,例如 Page.Controls.Add
我更喜欢返回数组而不是 List,原因有几个。
习惯。 1.0/1.1 中的集合很糟糕
我更喜欢我的方法返回最简单的 & 他们能做到的最轻量级的物体。 如果我需要将数组变成列表,这很简单。
它们可以在 .net 1.1 中使用,并且它可以减少重构的表面面积,如果我需要支持旧版本的运行时,我可以重用至少一些代码或应用相同的对象模型。
I think he maybe thought since an array's length property is immutable, then somehow arrays are more immutable than IList or maybe he used the wrong word and interchanged concrete with immutable. Who knows but it's an odd answer.
I think with returning a List there is something slightly implied that it's ok to modify it or that it may change while returning an array doesn't imply that as much.
For example, If you had an object model on top of a repository and had a method like GetCars() that returned a List and a junior programmer saw cars.Add(Car c) ... Would you think he was completely insane for thinking cars.Add(new Car()) might actually add a car into the repository? Arrays are just inherently more explicit.
I think List usage is more appropriate in properties, like Page.Controls.Add
I prefer returning arrays more often than List for several reasons.
Habit. Collections in 1.0/1.1 SUCKED
I prefer that my methods return the simplest & most lightweight object they can. If I need to make an Array a List it is trivial.
They can be used in .net 1.1 and it reduces the surface are of refactoring if I ever needed to support older versions of the runtime I can reuse at least some of my code or apply an identical object model.
我总是更喜欢 ReadOnlyCollection。 具有列表的所有优点,但只读。
I always prefer a ReadOnlyCollection. All the advantages of a List, but Read Only.
他的意思可能是 IList 包含 Insert、Remove 和 Add 方法,因此可以修改集合本身。 另一方面,T[] 不能向其中添加元素。
我应该补充一点,FxCop 建议返回 ReadOnlyCollection。 索引器是只读的,因此您无法更改元素,并且 Add 和其他此类方法都会抛出 NotSupportedException。
One point he could have meant is that IList includes the Insert, Remove, and Add methods, so the collection itself can be modified. T[], on the other hand, cannot have elements added to it.
I should add that FxCop recommends returning ReadOnlyCollection instead. The indexer is read-only, so you can't change the elements, and the Add and other such methods all throw NotSupportedException.
原则上他是对的,但他不知道如何正确实践......
那是对的。 不可变类型更适合使用
这是不正确的。 这些都不是一成不变的。
如果要返回不可变的集合,请返回
IEnumerable
或ReadOnlyCollection
(使用List.AsReadOnly< /代码> 方法)。 如果对象本身不是不可变的,那么这些仍然不能保护对象。 尽管您只能从集合中读取,但如果每个对象允许,您仍然可以更改每个对象中的数据。
此外,您还应该考虑您要归还的藏品的“所有权”。 如果您创建数组的唯一目的是返回它,那么没有理由不对其进行完全控制。 另一方面,如果您返回一个属于该类成员的集合,则应该只允许根据需要对其进行尽可能少的访问。
In principle he's right, but he doesn't know how to practice it properly...
That is correct. Immutable types are nicer to work with
That is not correct. Neither of those are immutable.
If you want to return a collection that is immutable, return an
IEnumerable<T>
or aReadOnlyCollection<T>
(using theList<T>.AsReadOnly
method). Still those doesn't protect the objects if they themselves are not immutable. Eventhough you can only read from the collections, you can still change the data in each object if they allow it.Also, you should consider the "ownership" of the collection that you are returning. If you are creating an array for the sole purpose of returning it, then there is no reason not to give full control to it. If you on the other hand are returning a collection that is a member of the class, you should only allow as little access to it as is needed.
我也不明白。 除了大小之外,数组的可变性非常大。 单个元素仍然可以修改。 也许他的意思是数组是值类型,列表是引用类型。 我不知道。
无论如何,您应该看看 埃里克·利珀特(Eric Lippert)对此主题的看法。 也可以为您提供一些讨论的弹药。
I don't understand it either. Arrays are very much mutable, except for their size. Individual elements can still be modified. Maybe he meant arrays are value types and Lists are reference types. I don't know.
Anyway, you should probably have a look at Eric Lippert's opinion on the subject. Could provide you with some ammo for discussion, too.
也许这个人不知道自己在说什么?
Perhaps this someone does not know what he is talking about?
使用接口作为实际类型本身的返回类型的原因是向调用者隐藏内部实现。 这允许实现更改实际类型,而不会影响应用程序的其余部分。
将内部使用的集合复制到数组中以供外部使用是没有任何意义的,除了可变或不可变之外没有其他原因。
单独的问题是:
- 是否返回强类型数据的列表。 IList 或 IList。
始终首选使用强类型数据。
- 可变或不可变。 ICollection、IList 或 IEnumerator
返回您想要允许的数据内容。 对于只读列表,仅返回 IEnumerator。 如果允许调用者修改集合,请使用 ICollection 或 IList。
The reason to use an Interface as return type over the actual type itself, is to hide the internal implementation from the caller. This allowes the implementation to change the actual type without repurcusions to the rest of the application.
It does not make any sense to copy an internally used collection into an array for external use, for no other reason than mutable or immutable.
Seperate issues are:
- return a list of strongly typed data or not. IList or IList.
The use of strongly typed data is always preferred.
- mutable or immutable. ICollection,IList or IEnumerator
Return with what you want to allow to the data. For a readonly list return only a IEnumerator. If the caller is allowed to modify the collection use ICollection or IList.
基本上他是说“我们更喜欢在运行时不易更改的结构,因为我们相信它们不易出错。” 在这种情况下这是否正确是另一个问题。
Basically he's saying "we prefer structures which can't be changed easily at run time, because we believe them to be less vulnerable to errors." Whether that's correct in this case is another question.