C# 如何制作此类自定义列表/集合
我正在尝试开发一个自定义集合或列表类,它为我提供以下功能:C# 如何制作此类自定义列表/集合,c#,list,collections,ienumerable,C#,List,Collections,Ienumerable,我正在尝试开发一个自定义集合或列表类,它为我提供以下功能: Add(MyObject) Add(MyObject, String) ' key Remove(MyObject) RemoveByKey(String) ' key RemoveAt(Index) Count Clear Item(Index) Item(String) ' key Contains(MyObject) ContainsKey(String) ' key GetEnumerator ' for-each
Add(MyObject)
Add(MyObject, String) ' key
Remove(MyObject)
RemoveByKey(String) ' key
RemoveAt(Index)
Count
Clear
Item(Index)
Item(String) ' key
Contains(MyObject)
ContainsKey(String) ' key
GetEnumerator ' for-each MyObject
我已经搜索了IEnumerable、IList和ICollection,但没有一个能满足我上面的需求。例如,它们都缺少按键(字符串)存储对象。
如何创建这样的集合/列表对象?我注意到,与我的需求最匹配的是系统可用的ListViewItemCollection对象。我希望我能看到其中的编码,以了解它是如何实现对象的存储和检索的
有人能帮忙吗?或者引导我找到教程链接
谢谢。此类类的示例可以是System.Windows.Forms.Control.ControlCollection,它的实现方式类似于
列表(实际上控件已经包含键),此[字符串]
使用普通for循环(线性搜索键)实现
我们可以通过添加Dictionary来帮助加快这一速度,并向两个集合(列表+Dictionary)添加每个具有键的项。不带键的项目仅添加到列表中
编辑:进一步的改进可以使用列表
和字典
-将索引从列表映射到字典,以便更快地删除。RemoveAt应检查键是否已预设,并将其从字典中删除。RemoveByKey可以获取内部List.RemoveAt的索引
基于注释的插件:IEnumerable的实现可能如下所示:
class MyObjectList<T>: IEnumerable<T> {
public IEnumerator<T> GetEnumerator() {
T[] a = items; int n = size;
for(int i = 0; i < n; i++)
yield return a[i]; }
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator(); }
类MyObjectList:IEnumerable{
公共IEnumerator GetEnumerator(){
T[]a=项目;int n=大小;
对于(int i=0;i
…以上是列表
插件:和(可以随意使用)。我打赌有很多更简单的方法可以做到这一点,但这里有一种方法。您可以创建一个结构,其中包含每个项目的键和值:
public sealed class Listionary<K, T> : IDictionary<K, T>, IList<T>
{
private struct ListionaryPair
{
public ListionaryPair(T item) : this()
{
Item = item;
}
public ListionaryPair(K key, T item) : this()
{
Key = key;
Item = item;
}
public K Key { get; private set; }
public T Item { get; private set; }
public bool HasKey { get; private set; }
}
private readonly List<ListionaryPair> list = new List<ListionaryPair>();
可以通过显式实现隐藏丑陋的方法:
void ICollection<KeyValuePair<K, T>>.CopyTo(KeyValuePair<K, T>[] array, int arrayIndex)
{
// code implementing the method
}
void ICollection.CopyTo(KeyValuePair[]数组,int-arrayIndex)
{
//实现该方法的代码
}
您需要一些助手方法来按键访问:
private int IndexOfKey(K key)
{
for (int i = 0; i < list.Count; i++)
{
var pair = list[i];
if (pair.HasKey && pair.Key == key)
{
return i;
}
}
return -1;
}
private int IndexOfKey(K键)
{
for(int i=0;i
但如果你做对了,剩下的就没有那么大的挑战了:
public T this[K key]
{
get
{
int index = IndexOfKey(key);
if (index < 0)
{
throw new IndexOutOfRangeException();
}
return list[index].Item;
}
set
{
int index = IndexOfKey(key);
if (index < 0)
{
throw new IndexOutOfRangeException();
}
list[index] = new ListionaryPair(key, value);
}
}
public T此[K键]
{
得到
{
int index=IndexOfKey(键);
如果(指数<0)
{
抛出新的IndexOutOfRangeException();
}
返回列表[索引]。项;
}
设置
{
int index=IndexOfKey(键);
如果(指数<0)
{
抛出新的IndexOutOfRangeException();
}
列表[索引]=新的ListionaryPair(键,值);
}
}
完成每个接口方法需要相当多的编码,但大多数都是简短的。您必须决定是否允许使用同一个键的多个项,是IDictionary.Clear()
清除整个集合还是只清除键控项,等等
此外,本例中没有支持字典
,因此性能可能不太好。听起来您需要一本字典。要添加到@SLaks注释中,Microsoft在此处为其字典
的实现提供了源代码:但这看起来更像是一本有序字典
,因为他想访问s项目也按索引。我将组合两个容器-带键的容器为字典,所有容器为列表。索引与键相关吗?@SLaks我不建议使用OrderedDictionary
,我将Dictionary
与他正在寻找的内容进行了比较。我不是要攻击你的评论,只是试图帮助提高速度不是问题。col我想我尝试开发的选择不会保留超过50个项目。但是在字典和列表中保留一个对象不是对内存的负担吗?如果速度不是问题,那么我会和ControlCollection一样。但是我喜欢优化速度,内存开销不会太大(比如*2或*3——这不是问题,速度可能会有问题)我使用一个内部列表和字典来管理Add、Remove、RemoveAt、RemoveByKey等。但是对于GetEnumerator,我认为我需要实现一些接口。它应该是IList还是IcolAction或者其他什么?GetEnumerator是足够的,但是你应该添加IEnumerable
接口。GetEnumerator()很简单:foreach(innerList中的KeyValuePair对)yield return pair.Value;
我检查了您的@firda ListCore示例以及我在网上找到的一些其他自定义集合源代码,我注意到许多自定义集合使用数组来处理它们的工作,而不是依赖于IList或ICollection之类的内置接口。这些接口上的性能真的很差吗必须求助于手动管理的数组?公共接口IDictionary:ICollection、IEnumerable、IEnumerable
…因此,我宁愿坚持使用KeyValuePair,并使用null表示无键…但是+1表示努力(回答很好,很长)。
public T this[K key]
{
get
{
int index = IndexOfKey(key);
if (index < 0)
{
throw new IndexOutOfRangeException();
}
return list[index].Item;
}
set
{
int index = IndexOfKey(key);
if (index < 0)
{
throw new IndexOutOfRangeException();
}
list[index] = new ListionaryPair(key, value);
}
}