我想创建一个包含唯一Type
键的项目"列表",该键由项目本身的类型键控。我创建了一个收藏Dictionary<Type, V>
并对其进行管理
internal class TypeCollection<V>
{
public TypeCollection()
{
items = new Dictionary<Type, V>();
}
private Dictionary<Type, V> items;
public void Add<T>(T value) where T : V
{
items.Add(typeof(T), value);
}
public void Remove(Type type)
{
items.Remove(type);
}
public bool TryGetValue<T>(out T value) where T : V
{
if (items.TryGetValue(typeof(T), out V foundValue))
{
value = (T)foundValue;
return true;
}
value = default(T);
return false;
}
}
我必须遍历这些值。for-loop
是不可能的,因为我必须按其类型访问值,但foreach-loop
可以完成这项工作。我实现了IEnumerable
接口
TypeCollection<V> : IEnumerable<V>
并添加了所需的接口方法
public IEnumerator<V> GetEnumerator()
{
foreach (V value in items.Values)
{
yield return value;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
当我想从该集合中删除所有值时,我必须实现这个
public void Clear()
{
items.Clear();
}
正如你可能已经注意到的那样,我本来打算重新发明一本词典,为什么我要这么做。。。
我创建了这个
internal class TypeCollection<V> : Dictionary<Type, V>
{
public void Add<T>(T value) where T : V
{
Add(typeof(T), value);
}
public bool TryGetValue<T>(out T value) where T : V
{
if (TryGetValue(typeof(T), out V foundValue))
{
value = (T)foundValue;
return true;
}
value = default(T);
return false;
}
}
但是我不能覆盖默认的CCD_ 6和CCD_。我总是有两种方法,Add
和Add<>
,那么什么是"最干净"的方法?我想隐藏默认的Add
和TryGetValue
方法,因为不再需要使用它们了。
您可以在System.Collections.Generic
:中使用现有的KeyedByTypeCollection<TItem>
,而不是创建自己的自定义TypeCollection<TValue>
KeyedByTypeCollection<TItem> Class
提供一个集合,该集合的项是用作键的类型。
备注
集合中只允许每种类型的一个对象,因为该类型是键,并且每个键必须是唯一的。但是你可以找到不同类型的物体。
然而,您可能需要将其子类化并扩展为包括一个方便的TryGetValue<T>(out T value)
,如
public class TypeCollection<V> : KeyedByTypeCollection<V>
{
public T ValueOrDefault<T>() where T : V
{
if (!Contains(typeof(T)))
{
return default(T);
}
return (T)this[typeof(T)];
}
public bool TryGetValue<T>(out T value) where T : V
{
if (!Contains(typeof(T)))
{
value = default(T);
return false;
}
value = (T)this[typeof(T)];
return true;
}
}
这是因为KeyedByTypeCollection<V>.Find<T>
方法返回指定类型T
集合中的第一个项,因此在具有复杂多态类型层次结构的情况下,当存在基类型时,它可能会返回派生类型的实例:
var dictionary = new KeyedByTypeCollection<object>();
dictionary.Add("hello");
dictionary.Add(new object());
Assert.IsTrue(dictionary.Find<object>().GetType() == typeof(object)); // FAILS
有关使用的更多示例,请参阅.Net?中KeyedByTypeCollection的使用。
您可以重新引入这些方法并使它们私有化:
private new void Add(Type key, V value)
{
}
private new bool TryGetValue(Type key, out V value)
{
value = default(V);
return false;
}
对于您的问题,有两种方法:继承和组合。继承不允许排除基类方法,因此Dictionary
不是适合您的类型的最佳基类。
在合成中没有这样的问题,因为你决定了要公开什么方法。这是正常的方式。
解决方案:使用组合或找到新的更好的基类。
改为实现IDictionary
接口:
internal class TypeCollection<V> : IDictionary<Type, V>
{
protected readonly Dictionary _innerDictionary = new Dictionary<Type,V>();
}
一旦您键入了那么多,VisualStudio就会在部分代码下加下划线,并显示一个错误,提醒您尚未实现该接口。右键单击错误并选择"通过_innerDictionary实现接口",它将自动生成将方法连接到_innerDictionary
所需的一切。然后你可以修改任何你想要的。