我不清楚以上陈述。如果有人可以解释我们如何使用继承来创建自定义,类型安全和空安全集合,那会很棒吗?
由于
答案 0 :(得分:3)
好吧,您可以从Collection<T>
派生一个新类型并覆盖SetItem
和InsertItem
:如果新值为null,则抛出异常。那是你想到的那种吗?
那将是:
Collection<T>
;基类可以防止添加不适当类型的值你甚至可以保持通用:
// Note: you could include "where T : class"; on the other hand
// you might have some reason to want a NullSafeCollection<int?>
// which you knew had no null values in.
public class NullSafeCollection<T> : Collection<T>
{
protected override InsertItem(int index, T item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
base.InsertItem(index, item);
}
// Likewise for SetItem
}
答案 1 :(得分:2)
我认为问题在于模糊的术语“无效安全”。
通常,对于类型安全集合,您使用泛型而不是继承。
所以我想我们想要的是一个派生集合,它在一些标准泛型集合之上添加了“null安全检查”(在你的情况下意味着什么)。除了在C#中,泛型集合不使用虚函数,因此它们不能被扩展(无论是谁而选择在没有密封类的情况下这样做也应该永远禁止编程)。
因此,您必须使用旧的.NET 1.x非泛型集合(如Collection),并使用“类型安全检查”和“空安全检查”覆盖它们。
另一方面,如果您使用的是“null safe”,那么更常见的集合,例如List<T>
,LinkedList<T>
,Stack<T>
,{{1已经“空安全”,因为如果你传递Queue<T>
它们不会崩溃或产生异常。另一方面,null
不是空安全的,因为它在参数上调用GetHashCode。您必须重新编写它们以定义Dictionary<TKey,TValue>
的哈希码。 null
实际上是这样做的,将HashSet<T>
定义为0
的哈希值。同样,对于null
和SortedList<TKey,TValue>
,您必须定义排序顺序中SortedDictionary<TKey,TValue>
的位置。
据我所知,没有办法让这些集合表现正常。这些类中缺少null
支持不是由传入null
时散列函数或比较器失败引起的,而是由所有面向公众的API中的先发制人检查引起的。这些不能通过公共继承来修复,而C#(通常是.NET)不允许私有继承。从好的方面来说,null
不会让底层词典看不到空键。但是它扩展System.Collections.ObjectModel.KeyedCollection<TKey,TItem>
以通过包含而不是继承来增加空安全性。