C# 该列表显示调试器中的4项,即使只填充了一个元素

C# 该列表显示调试器中的4项,即使只填充了一个元素,c#,linq,distinct,tolist,C#,Linq,Distinct,Tolist,当我在调试器中查看由单个项填充的列表时,它的\u items字段包含4个元素。你能解释一下这种行为吗 我发现,在调试控制台应用程序以了解Distinct和ToList以及结果时,我感到困惑。代码: List<int> nums = new List<int>() { 6, 6, 6, 6, 6, 6, 6, 6 }; List<int> distinctNums = nums.Distinct().ToList(); int[] distinctNums2 =

当我在调试器中查看由单个项填充的列表时,它的
\u items
字段包含4个元素。你能解释一下这种行为吗

我发现,在调试控制台应用程序以了解
Distinct
ToList
以及结果时,我感到困惑。代码:

List<int> nums = new List<int>() { 6, 6, 6, 6, 6, 6, 6, 6 };
List<int> distinctNums = nums.Distinct().ToList();
int[] distinctNums2 = nums.Distinct().ToArray();
List nums=newlist(){6,6,6,6,6,6};
List distinctNums=nums.Distinct().ToList();
int[]distinctNums2=nums.Distinct().ToArray();
  • distinctNums
    \u项中有4个元素
    (6,0,0)
    ,这显然是错误的
  • distinctNums2
    有一项是正确的
    (6)

这将创建仅包含一项的列表,正如您所期望的那样。但是,.NET中的列表由一个数组支持,当您向其中添加项时,该数组会自动调整大小。该数组以4大小开始,因此如果您碰巧通过反射或在调试器中对其进行探测,则内部数组将是
[4,0,0,0]


但是如果您进行检查,您会发现
distinctNums.Count==1
。比较和属性。

两个
distinctNums
distinctNums2
实际上只包含一个对象

在调试器中看到的包含四项的列表只是支持
列表的数组。您可以看到它的
计数
1
,如果您迭代列表,它只返回一个
6

list
T[]
之上的一个抽象(标准数组)。数组的大小无关紧要。当您为
列表
分配一个项目时,编译器不会分配
新的T[1]
,这会给您一些增长空间(当您超出原始数组时,它必须重新分配一个新数组并复制项目,这是一个相对昂贵的操作)
Count
给出列表长度,如果在该列表中调用,将得到1。其他三个索引的默认值为零,它们不是列表的一部分,而是基础数组的一部分。它们不相关。如果您尝试执行myList[3]
操作,仍然会得到一个异常,它不会只返回0


要回到原来的问题,在这两种情况下,
Distinct
返回一个项目,并且
IEnumerable
返回一个项目。当您调用
ToList
时,它会分配一个新列表,计数为1,它的底层数据结构是一个起始长度为4的
int[]
。如果您添加更多的项目,它将增长。在第二个示例中,您调用
ToArray
,因此它分配了一个新的
int[1]
,并返回对它的引用。

两者都返回列表中的一个元素,您如何检查结果?我显著地更新了您的帖子,以反映调试器的参与。如果您不喜欢,请随意编辑。看起来OP使用了
容量
来检查项目数?太可怕了。+1@KingKing-更可能的是OP只是点击“+”直到看到第一个实际字段(试着在调试时查看VS编辑器中的列表,然后点击“原始视图”)@AlexeiLevenkov是的,我刚刚试过,它是内部数组
\u项
。一开始,他就应该看到公众成员只显示了1项
[0]
,值
6
。正如@Alexei Levenkov所说,我在调查一个问题时只是查看原始数据,这让我大吃一惊。本以为是它引起了我的bug,但结果不是。谢谢@p.s.w.g我不知道这一点。