我有以下实现
// Contains returns true if the specified element is in the List.
// It does a linear, O(n) search. Equality is determined by calling
// item.Equals().
//
public bool Contains(T item) {
if ((Object) item == null) {
for(int i=0; i<_size; i++)
if ((Object) _items[i] == null)
return true;
return false;
}
else {
EqualityComparer<T> c = EqualityComparer<T>.Default;
for(int i=0; i<_size; i++) {
if (c.Equals(_items[i], item)) return true;
}
return false;
}
}
如果item
是struct
值类型,流量是否会进入if
块,而不是else
块?
我对这个实现很困惑。
有人可以向我解释Contains
方法如何评估价值类型,例如struct
?
答案 0 :(得分:2)
if
部分仅检查我们是否在列表中查找null
项。如果我们这样做,那么它将遍历列表并在列表的项目中查找null
值。此部分仅对引用类型有效,因为值类型不能是null
。
另一只手的else
部分在项目不是null
的情况下进行所有检查,因此此代码也用于structs
。它的作用是获取类型(EqualityComparer<T> c = EqualityComparer<T>.Default
)的默认相等比较器,并使用此比较器查找列表中的项目。
答案 1 :(得分:1)
您需要了解的是value type
和reference type
之间的区别。
struct
,就像int
,long
等一样,不存储在heap
上,而是存储在stack
上。 reference type
有一个指针(存储地址)存储在stack
上,指向实际对象数据存储在heap
上。
(请阅读堆栈与堆之间的差异。)
但是,将struct
添加到ArrayList
甚至List<object>
之类的内容仍然有用,因为它最有可能首先被装入reference type
,因此{ {1}} 不 struct
,即使您通过了null
,它仍然不是 default(<struct type>)
。
然后就会像@dotnetom一样解释null
部分正在执行并评估一个else
是否在集合中。