You can have a runtime enforced constraint on your collection like this:
public class ConstrainedTypeCollection<TBaseType> : Collection<Type>
{
protected override void InsertItem(int index, Type item)
{
if (!typeof(TBaseType).IsAssignableFrom(item))
throw new ArgumentException("The type is incompatible.", "item");
base.InsertItem(index, item);
}
protected override void SetItem(int index, Type item)
{
if (!typeof(TBaseType).IsAssignableFrom(item))
throw new ArgumentException("The type is incompatible.", "item");
base.SetItem(index, item);
}
}
Edit: You could also do the following and get full compile-time type safety as long as you call the generic Add<T>()
, Contains<T>()
, and Remove<T>()
methods.
public class ConstrainedTypeCollection<TBaseType> : ICollection<Type>
{
private readonly List<Type> _collection = new List<Type>();
public void Add<T>()
where T : TBaseType
{
_collection.Add(typeof(T));
}
public bool Contains<T>()
where T : TBaseType
{
return _collection.Contains(typeof(T));
}
public bool Remove<T>()
where T : TBaseType
{
return _collection.Remove(typeof(T));
}
public int Count
{
get
{
return _collection.Count;
}
}
bool ICollection<Type>.IsReadOnly
{
get
{
return false;
}
}
public void Clear()
{
_collection.Clear();
}
public void CopyTo(Type[] array, int arrayIndex)
{
_collection.CopyTo(array, arrayIndex);
}
public IEnumerator<Type> GetEnumerator()
{
return _collection.GetEnumerator();
}
#region ICollection<Type> Members
void ICollection<Type>.Add(Type item)
{
VerifyType(item);
_collection.Add(item);
}
bool ICollection<Type>.Contains(Type item)
{
VerifyType(item);
return _collection.Contains(item);
}
bool ICollection<Type>.Remove(Type item)
{
VerifyType(item);
return _collection.Remove(item);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private void VerifyType(Type item)
{
if (!typeof(TBaseType).IsAssignableFrom(item))
throw new ArgumentException("The type is incompatible.", "item");
}
}