我需要在自己的课程中维护集合语义。您无法解释,集合语义是什么?据我了解,它是一组必须在类中实现的接口。是真的吗如果是的话,我该在课堂上具体实施什么?为什么?这两个接口(ICollection和IEnumerable)是否足够,还是仅是最必要的接口?
我正在使用this article作为帮助编写循环链表。
最佳答案
.NET中有很多集合类型,它们都有一些共同的行为,例如:
您可以使用foreach
枚举它们
他们有一个Count
属性
您可以使用Add
方法添加项目
等等...
从集合类型可以预料到这种行为,您猜对了:都在ICollection<T>
界面中。让我们看一下接口层次结构:IEnumerable<T>
允许使用foreach
枚举您的班级ICollection<T>
是表示集合的IEnumerable<T>
:
它允许检索项目Count
您可能可以从集合中Add
/ Remove
/ Clear
个项目
集合可能是只读的,在这种情况下,IsReadOnly
应该返回true
还有其他一些辅助方法:Contains
/ CopyTo
。IList<T>
是允许通过索引访问项目的ICollection<T>
。
它添加了一个索引器
一些与索引相关的功能:Insert
/ RemoveAt
IndexOf
您应该实现哪个接口取决于语义:IEnumerable<T>
只是一个可枚举的序列。只能通过使用代码来枚举一次,因为您永远不知道它在多个枚举中的表现方式。如果多次枚举IEnumerable<T>
,诸如ReSharper之类的工具甚至会发出警告。
当然,大多数时候您可以安全地枚举它多次,但是有些时候您不应该这样做。例如,一个枚举可以执行一个SQL查询(例如,以Linq-to-SQL为例)。
通过定义一个函数来实现IEnumerable<T>
:GetEnumerator
返回en IEnumerator<T>
。枚举数是一个对象,是一种指向序列中当前元素的指针。它可以返回该Current
值,并且可以使用MoveNext
移至下一个元素。它也是一次性的(并在foreach
的枚举末尾放置)。
让我们分解一个foreach
循环:
IEnumerable<T> sequence = ... // Whatever
foreach (T item in sequence)
DoSomething(item);
这等效于以下内容:
IEnumerator<T> enumerator = null;
try
{
enumerator = sequence.GetEnumerator();
while (enumerator.MoveNext())
{
T item = enumerator.Current;
DoSomething(item);
}
}
finally
{
if (enumerator != null)
enumerator.Dispose();
}
记录上,严格要求实现
IEnumerable
才能使类可用于foreach
。鸭子在这里打字就足够了,但我的话太多了。当然,您可以使用
yield
关键字轻松实现该模式:public static IEnumerable<int> GetAnswer()
{
yield return 42;
}
这将创建一个私有类,该类将为您实现
IEnumerable<int>
,因此您不必这样做。ICollection<T>
表示一个集合,可以安全地多次枚举。但是您真的不知道它是什么样的收藏。它可以是集合,列表,字典等。这就是集合的语义。
一些例子:
T[]
-即使您不能ICollection<T>
/ Add
,它也会实现Remove
List<T>
HashSet<T>
-一个很好的集合示例,但没有列表Dictionary<TKey, TValue>
-是的,这是一个ICollection<KeyValuePair<TKey, TValue>>
LinkedList<T>
ObservableCollection<T>
IList<T>
让您知道集合的类型,该集合使您可以轻松地按索引访问元素(即O(1)时间)。对于您的循环链表,情况并非如此,因为它不仅需要O(n)时间,而且首先没有有意义的索引。
一些例子:
T[]
List<T>
ObservableCollection<T>
请注意,例如
HashSet<T>
和Dictionary<TKey, TValue>
不再在列表中。这些不是列表。 LinkedList<T>
在语义上是一个列表,但在O(1)时间内不提供按索引的访问(它需要O(n))。我应该提到在.NET 4.5中存在的只读等效项:
IReadOnlyCollection<out T>
,IReadOnlyList<out T>
。这些对于它们提供的协方差很好。
关于c# - 什么是集合语义(在.NET中)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26202036/