C# 创建自定义泛型集合
我想创建一个自定义的通用集合,如果元素少于10个,它将存储在C# 创建自定义泛型集合,c#,collections,C#,Collections,我想创建一个自定义的通用集合,如果元素少于10个,它将存储在列表中;如果元素较多,则存储在分类列表中 我为SortedList实现了ICollection(KeyValuePair),为List实现了ICollection,但我不知道接下来该怎么做。请有人给我一个提示,如果元素少于10个,应该如何实现“将元素存储在列表中”,如果元素较多,应该如何实现“将元素存储在分类列表中” class CustomCollection<T, V> : ICollection<KeyValue
列表
中;如果元素较多,则存储在分类列表
中
我为SortedList
实现了ICollection(KeyValuePair)
,为List
实现了ICollection
,但我不知道接下来该怎么做。请有人给我一个提示,如果元素少于10个,应该如何实现“将元素存储在列表中”
,如果元素较多,应该如何实现“将元素存储在分类列表中”
class CustomCollection<T, V> : ICollection<KeyValuePair<T, V>>, ICollection<T>
{
private readonly ICollection<T> _list = new List<T>();
private readonly ICollection<KeyValuePair<T, V>> _sortlist = new SortedList<T, V>();
public void Add(KeyValuePair<T, V> item)
{
_sortlist.Add(item);
}
public void Add(T item)
{
_list.Add(item);
}
}
类CustomCollection:ICollection,ICollection
{
私有只读ICollection_list=new list();
私有只读ICollection_sortlist=new SortedList();
公共作废添加(KeyValuePair项)
{
_分类表添加(项目);
}
公共作废新增(T项)
{
_列表。添加(项目);
}
}
这里是完整的实现。它相当长,完全未经测试:-)您可以从调试中获得乐趣
有一些有趣的地方:两个比较器的使用(不是一个好主意),如何处理null
(它抛出null引用异常
,如SortedList),以及在各种添加
,删除
,清除
集合之间的切换。请注意,通常SortedList
“隐藏”所有直接处理KeyValuePair
的方法。我选择了做同样的事情。其他注意事项:要在列表中“搜索”,我将进行线性搜索。更聪明(更快)的方法是执行列表.BinarySearch
public class CustomCollection<TKey, TValue> : IDictionary<TKey, TValue>
{
protected List<KeyValuePair<TKey, TValue>> List { get; set; }
protected SortedList<TKey, TValue> SortedList { get; set; }
// Two comparers needed: an EqualityComparer and a Comparer to sort
// We could simply use the Comparer and compare the result to 0
// instead of using an EqualityComparer and a Comparer
protected readonly EqualityComparer<TKey> EqualityComparer = EqualityComparer<TKey>.Default;
protected readonly Comparer<TKey> Comparer = Comparer<TKey>.Default;
public int MaxCapacityList { get; protected set; }
public CustomCollection(int maxCapacityList = 10)
{
MaxCapacityList = maxCapacityList;
if (maxCapacityList > 0)
{
List = new List<KeyValuePair<TKey, TValue>>();
}
else
{
SortedList = new SortedList<TKey, TValue>();
}
}
public bool IsUsingList
{
get
{
return List != null;
}
}
public void Add(TKey key, TValue value)
{
if (IsUsingList)
{
if (key == null)
{
throw new ArgumentNullException();
}
if (List.Any(x => EqualityComparer.Equals(x.Key, key)))
{
throw new ArgumentException();
}
}
if (IsUsingList && List.Count < MaxCapacityList)
{
List.Add(new KeyValuePair<TKey, TValue>(key, value));
// Only place we need to sort. Only "real" Add method
List.Sort((x, y) => Comparer.Compare(x.Key, y.Key));
}
else
{
if (IsUsingList && List.Count == MaxCapacityList)
{
SortedList = new SortedList<TKey, TValue>();
foreach (var kv in List)
{
SortedList.Add(kv.Key, kv.Value);
}
List = null;
}
SortedList.Add(key, value);
}
}
public bool ContainsKey(TKey key)
{
if (IsUsingList)
{
if (key == null)
{
throw new ArgumentNullException();
}
if (List.Any(x => EqualityComparer.Equals(x.Key, key)))
{
return true;
}
return false;
}
return SortedList.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get
{
if (IsUsingList)
{
return List.ConvertAll(x => x.Key);
}
return SortedList.Keys;
}
}
public bool Remove(TKey key)
{
if (IsUsingList)
{
if (key == null)
{
throw new ArgumentNullException();
}
for (int ix = 0; ix < List.Count; ix++)
{
if (EqualityComparer.Equals(List[ix].Key, key))
{
List.RemoveAt(ix);
return true;
}
}
return false;
}
bool result = SortedList.Remove(key);
if (result && SortedList.Count == MaxCapacityList && MaxCapacityList > 0)
{
List = new List<KeyValuePair<TKey, TValue>>();
foreach (var kv in SortedList)
{
List.Add(new KeyValuePair<TKey, TValue>(kv.Key, kv.Value));
}
SortedList = null;
}
return result;
}
public bool TryGetValue(TKey key, out TValue value)
{
if (IsUsingList)
{
if (key == null)
{
throw new ArgumentNullException();
}
for (int i = 0; i < List.Count; i++)
{
if (EqualityComparer.Equals(List[i].Key, key))
{
value = List[i].Value;
return true;
}
}
value = default(TValue);
return false;
}
return SortedList.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get
{
if (IsUsingList)
{
return List.ConvertAll(x => x.Value);
}
return SortedList.Values;
}
}
public TValue this[TKey key]
{
get
{
if (IsUsingList)
{
if (key == null)
{
throw new ArgumentNullException();
}
for (int ix = 0; ix < List.Count; ix++)
{
if (EqualityComparer.Equals(List[ix].Key, key))
{
return List[ix].Value;
}
}
throw new KeyNotFoundException();
}
return SortedList[key];
}
set
{
if (IsUsingList)
{
if (key == null)
{
throw new ArgumentNullException();
}
for (int ix = 0; ix < List.Count; ix++)
{
if (EqualityComparer.Equals(List[ix].Key, key))
{
List[ix] = new KeyValuePair<TKey, TValue>(key, value);
return;
}
}
Add(key, value);
return;
}
SortedList[key] = value;
}
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}
public void Clear()
{
if (IsUsingList)
{
List.Clear();
}
else
{
if (MaxCapacityList > 0)
{
List = new List<KeyValuePair<TKey, TValue>>();
SortedList = null;
}
else
{
SortedList.Clear();
}
}
}
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
if (IsUsingList)
{
if (item.Key == null)
{
throw new ArgumentNullException();
}
return List.Any(x => EqualityComparer.Equals(x.Key, item.Key));
}
return ((ICollection<KeyValuePair<TKey, TValue>>)SortedList).Contains(item);
}
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
if (IsUsingList)
{
List.CopyTo(array, arrayIndex);
return;
}
((ICollection<KeyValuePair<TKey, TValue>>)SortedList).CopyTo(array, arrayIndex);
}
public int Count
{
get { return IsUsingList ? List.Count : SortedList.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
if (IsUsingList)
{
if (item.Key == null)
{
throw new ArgumentNullException();
}
for (int ix = 0; ix < List.Count; ix++)
{
if (EqualityComparer.Equals(List[ix].Key, item.Key))
{
var comparer2 = EqualityComparer<TValue>.Default;
if (comparer2.Equals(List[ix].Value, item.Value))
{
List.RemoveAt(ix);
return true;
}
return false;
}
}
return false;
}
bool result = ((ICollection<KeyValuePair<TKey, TValue>>)SortedList).Remove(item);
if (result && SortedList.Count == MaxCapacityList && MaxCapacityList > 0)
{
List = new List<KeyValuePair<TKey, TValue>>();
foreach (var kv in SortedList)
{
List.Add(new KeyValuePair<TKey, TValue>(kv.Key, kv.Value));
}
SortedList = null;
}
return result;
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return IsUsingList ? List.GetEnumerator() : SortedList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
// Chained to the other GetEnumerator()
return GetEnumerator();
}
}
公共类CustomCollection:IDictionary
{
受保护列表{get;set;}
受保护的分类列表分类列表{get;set;}
//需要两个比较器:一个EqualityComparer和一个用于排序的比较器
//我们可以简单地使用比较器并将结果与0进行比较
//而不是使用EqualityComparer和比较器
受保护的只读EqualityComparer EqualityComparer=EqualityComparer.Default;
受保护的只读比较器Comparer=Comparer.Default;
public int MaxCapacityList{get;protected set;}
公共CustomCollection(int maxCapacityList=10)
{
MaxCapacityList=MaxCapacityList;
如果(maxCapacityList>0)
{
列表=新列表();
}
其他的
{
SortedList=新的SortedList();
}
}
公共图书馆正在使用列表
{
得到
{
返回列表!=null;
}
}
公共无效添加(TKey键,TValue值)
{
如果(正在使用列表)
{
if(key==null)
{
抛出新ArgumentNullException();
}
if(List.Any(x=>EqualityComparer.Equals(x.Key,Key)))
{
抛出新ArgumentException();
}
}
if(使用列表和列表计数Comparer.Compare(x.Key,y.Key));
}
其他的
{
if(IsUsingList&&List.Count==MaxCapacityList)
{
SortedList=新的SortedList();
foreach(列表中的var kv)
{
分类列表。添加(千伏键,千伏值);
}
列表=空;
}
SortedList.Add(键、值);
}
}
公共bool ContainsKey(TKey)
{
如果(正在使用列表)
{
if(key==null)
{
抛出新ArgumentNullException();
}
if(List.Any(x=>EqualityComparer.Equals(x.Key,Key)))
{
返回true;
}
返回false;
}
返回分拣列表。集装箱箱(钥匙);
}
公共ICollection密钥
{
得到
{
如果(正在使用列表)
{
返回List.ConvertAll(x=>x.Key);
}
返回分类列表。键;
}
}
公用门移除(TKey)
{
如果(正在使用列表)
{
if(key==null)
{
抛出新ArgumentNullException();
}
for(intix=0;ix0)
{
列表=新列表();
foreach(分类列表中的var kv)
{
添加(新的KeyValuePair(千伏键,千伏值));
}
SortedList=null;
}
返回结果;
}
公共bool TryGetValue(TKey键,out TValue值)
{
如果(正在使用列表)
{
if(key==null)
{
抛出新ArgumentNullException();
}
for(int i=0;ix.Value);
}
返回分类列表值;
}
}
公共TValue此[TKey]
{
得到
{
如果(正在使用列表)
{