编程语言
首页 > 编程语言> > c# – 什么是集合语义(在.NET中)?

c# – 什么是集合语义(在.NET中)?

作者:互联网

我需要在自己的类中维护集合语义.你不能解释一下,什么是集合语义?据我所知,它是一组必须在类中实现的一些接口.这是真的吗?如果是的话 – 我必须在课堂上实现什么?为什么?这两个接口–ICollection和IEnumerable – 是否足够,或者这些只是最必要的接口?

我正在编写一个使用this article作为帮助的循环链表.

解决方法:

.NET中有许多集合类型,它们都有一些共同的行为,例如:

>您可以使用foreach枚举它们
>他们有一个Count属性
>您可以使用Add方法添加项目
>等……

这种行为是从集合类型中得到的,你猜对了:它全部在ICollection< T>中了.接口.我们来看看接口层次结构:

> IEnumerable< T>允许使用foreach枚举您的类
> ICollection< T>是IEnumerable< T>代表一个集合:

>它允许检索项目计数
>您可以添加/删除/清除集合中的项目
>集合只能是只读的,在这种情况下,IsReadOnly应该返回true
>还有其他一些辅助方法:Contains / CopyTo.

> IList< T>是ICollection< T>允许通过索引访问项目.

>它添加了一个索引器
>一些与索引相关的函数:Insert / RemoveAt
> IndexOf

您应该实现哪个接口是语义问题:

IEnumerable的&LT T&GT只是一个可枚举的序列.它只应通过使用代码枚举一次,因为您永远不知道它在多个枚举上的行为方式.像ReSharper这样的工具甚至会在你枚举IEnumerable< T>时发出警告.多次.
当然,大多数时候你可以安全地多次枚举它,但有时你不应该.例如,枚举可以执行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&LT T&GT表示一个集合,可以安全地多次枚举.但你真的不知道它是什么样的集合.它可以是一个集合,一个列表,一个字典,等等.

这是集合语义.

一些例子:

> T [] – 它实现ICollection< T>即使你不能添加/删除
>列表< T>
> HashSet< T> – 一个很好的集合示例,但不是列表
>字典< TKey,TValue> – 是的,那是ICollection< KeyValuePair< TKey,TValue>>
> LinkedList< T>
> ObservableCollection< T>

的IList&LT T&GT让您知道该集合是允许您轻松地通过索引访问元素的类型(即在O(1)时间内).

这不是你的循环链表的情况,因为它不仅需要O(n)时间,而且首先没有有意义的索引.

一些例子:

> T []
>列表< T>
> ObservableCollection< T>

注意HashSet< T>和词典< TKey,TValue>例如,不再列在列表中.这些不是列表.链表&LT T&GT在语义上是一个列表,但它在O(1)时间内不提供索引访问(它需要O(n)).

我应该提一下,在.NET 4.5中有只读的等价物:IReadOnlyCollection< out T&gt ;,IReadOnlyList< out T>.这些对他们提供的协方差很有帮助.

标签:c,net,collections,interface,semantics
来源: https://codeday.me/bug/20190715/1466896.html