关于C# Stack<T> Contains方法中拆箱为Object与null比较必要性的疑问
关于C# Stack.Contains方法中拆箱为Object后判断null的原因
先看对应的源码:
public bool Contains(T item) { int count = _size; EqualityComparer<T> c = EqualityComparer<T>.Default; while (count-- > 0) { if (((Object) item) == null) { if (((Object) _array[count]) == null) return true; } else if (_array[count]!= null && c.Equals(_array[count], item) ) { return true; } } return false; }
这个写法的核心目的是让代码兼容泛型参数T的所有可能类型(值类型和引用类型),具体原因分三点:
解决值类型的编译错误:如果T是值类型(比如
int、自定义struct),直接写item == null会编译失败——值类型本身不能被赋值为null。将T强制转换为Object后,值类型会被装箱,而装箱后的值类型实例永远不可能是null,这部分判断会直接跳过,既避免了编译报错,又不影响正常逻辑。统一引用类型的空值判断逻辑:对于引用类型,
(Object)item == null和直接item == null的效果完全一致,但这样写能让同一段代码同时处理值类型和引用类型的场景,不需要额外分支判断T的类型,简化了代码结构。提前规避Equals方法的空指针风险:如果直接调用
c.Equals(_array[count], item),当其中一个参数为null时,某些自定义的EqualityComparer<T>实现可能会抛出NullReferenceException。先把元素转成Object判断是否为null,就能提前处理空值情况,确保后续调用Equals时参数都是非空的,避免异常抛出。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

