public class List<T>
{
public int Count
{
get;
}
}
我注意到Count
是一个int
类型的变量,那么它的结果会小于0吗?
如果Count
可能小于0
,我必须写成:
if(myList.Count < 1)
{
}
否则我可以写成这样:
if(myList.Count == 0)
{
}
public class List<T>
{
public int Count
{
get;
}
}
我注意到Count
是一个int
类型的变量,那么它的结果会小于0吗?
如果Count
可能小于0
,我必须写成:
if(myList.Count < 1)
{
}
if(myList.Count == 0)
{
}
根据评论:
只是为了安全起见,因为我注意到计数器是一个
int
但不是一个uint
当设计List<T>
类时,微软的.NET类库设计规则意味着UInt32
(也称为uint
)不能用于任何public
成员,因此使用了Int32
(也称为int
)。
List<T>.Count
永远不会是负数或无效的,因为它只返回列表中元素的数量,这个数量总是非负整数。原因是Count
是一个Int32
属性,而不是UInt32
属性,因为List<T>
类型在Microsoft仍然尊重公共语言规范(CLS)时被定义,而Int32
符合CLS,而UInt32
不符合CLS。虽然.NET Core发布后没有正式废除CLS,但.NET生态系统似乎已经放弃了这个特性。
只要您以安全的方式使用 List<T>
实例,那么不会,.Count
属性始终会返回在 0
到 2^31
范围内的值(实际上一个 List<T>
的最大计数是一个不同的问题,在这里已经有答案了)。
然而,如果您以 线程不安全 的方式使用 List<T>
(例如,有 2 个或更多线程同时向列表中添加和删除项但没有正确地使用 lock
),或者如果您使用反射等技巧来覆盖 .Count
属性的字段值,则是,您可能会破坏事情。所以不要这样做 :)
- 为了启用完整的互操作性场景,所有在代码中创建的对象必须依赖于消费它们的语言(它们的调用者)中的某些共同点。
- 由于有许多不同的语言,.NET已经在称为公共语言规范(CLS)的东西中指定了这些共性。
公共语言规范在这篇MSDN文章中有描述,其中列出了内置于.NET中但在符合CLS的框架和可再分发库中是禁用的类型。
System.SByte
也叫做sbyte
。
System.UInt16
也叫做 ushort
。System.UInt32
也叫做 uint
。System.UInt64
也叫做 ulong
。System.UIntPtr
。另外:
- CLS符合性规则仅适用于组件的公共接口,而不适用于其私有实现。
- 例如,除
Byte
之外的无符号整数均不符合CLS [...].
public int Count {
get {
Contract.Ensures(Contract.Result<int>() >= 0);
return _size;
}
}
public int Count => _size;
_size
本身根据代码中的所有赋值操作不可能小于零。
_size
本身永远不可能小于零。”- 如果你以线程不安全的方式使用 List<T>
,则可以。 - Dai[TestFixture]
public class TotalGarbageTests
{
[Test]
public void Blasphemy()
{
var list = new List<int>();
list.GetType().GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(list, -666);
Assert.AreEqual(-666, list.Count);
}
}
.Count
(以及 .Count()
...和.Length
)的检查也应该检查负值,并且会使周围的每个人都感到烦恼。 - Alexei Levenkov
System.Collections.Generic.List<T>
还是你自己的List<T>
? - bolov< 0
理论上是可能的(因为如果您以非线程安全的方式使用类,则“所有赌注都关闭”)。但如果是这种情况,那么您将面临更大的问题 - 所以不要担心它。只需检查== 0
即可。 - mjwillsAny()
),并且忽略了int Count
可以(不能)为负数的原因,尽管现在我对这些是否真正重复有所疑虑。 - Lance U. Matthews