gpt4 book ai didi

c# - 即使使用具有容量的构造函数,列表 C# 容量始终为 0?

转载 作者:太空宇宙 更新时间:2023-11-03 19:56:37 25 4
gpt4 key购买 nike

给定这个简单的同步代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Mutex
{
class CalcArrayThreads
{
private static System.Threading.Mutex mutex = new System.Threading.Mutex();
private const int ThreadsNumber = 10;
private static List<int> list = new List<int>(10);
public static void SumPartialArray(object index)
{
mutex.WaitOne();
int indexBoxed = (int) index;
int sum = 0;
for (int i = indexBoxed; i < indexBoxed + 9; i++)
{
sum += i;
}
Console.WriteLine(string.Format("Thread : {0} Calculated value : {1}", Thread.CurrentThread.Name, sum));

// list.Add(sum);
list[indexBoxed] = sum;
mutex.ReleaseMutex();
// Console.WriteLine(list.Count());
}
static void Main(string[] args)
{
for (int i = 0; i < ThreadsNumber; i++)
{
Thread myThread = new Thread(new ParameterizedThreadStart(SumPartialArray));
myThread.Name = String.Format("Thread{0}", i + 1);
myThread.Start(i);
}
Console.Read();
}
}
}

当我使用这条线时:

list[indexBoxed] = sum;

我得到:

Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

即使列表的容量是 10 。

为什么?

最佳答案

如果您只是对数组执行以下操作,它会按预期工作,设置第二个元素:

int[] list = new int[10];

list[2] = 5; // second element is 5, no exception thrown

查看 List<T>构造函数,当你传入一个容量时,它实际上是在使用一个内部数组做一些非常相似的事情:

this._items = new T[capacity];

因此,当您尝试访问小于容量的任何元素时,它似乎应该工作,但索引器的实现方式如下:

public T this[int index]
{
get
{
if (index >= this._size)
throw new ArgumentOutOfRangeException("...");
return this._items[index];
}
set
{
if (index >= this._size)
throw new ArgumentOutOfRangeException("...");
this._items[index] = value;
}
}

它实际上是在检查 _size首先是变量,如果 index 则抛出异常你要求的比它大。如果没有那张支票,它会按您预期的那样工作。

_size除非将非空集合传递给构造函数,否则初始化为 0,并在使用 Add 时更改值, RemoveAt , Clear等方法。在内部,它仍然只是使用数组来存储元素,如果 _size大于容量(例如,在尝试 Add 一个元素之后),它会分配一个新数组并将旧(较小)数组中的所有元素复制到其中。

我看到您可以考虑使用两种解决方案:

要么只使用一个数组,像这样:

private static int[] list = new int[10];

或者通过构造函数提供一些默认值的集合(这里是一堆零):

private static List<int> list = new List<int>(Enumerable.Repeat(0, 10));

关于c# - 即使使用具有容量的构造函数,列表 C# 容量始终为 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33051064/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com