浅复制值类型数组的一部分

4
我正在尝试将double[]浅复制到各个片段,并将这些片段传递给新的线程,代码如下:

for (int i = 0; i < threadsArray.Length; i++)
{
    sub[i] = new double[4];

    //Doesn't shallow copy since double is a value type
    Array.Copy(full, i * 4, sub[i], 0, 4);
    double[] tempSub = sub[i];

    threadsArray[i] = new Thread(() => DoStuff(tempSub));
    threadsArray[i].Start();               
}

什么是将创建的段引用原始数组的最佳方法?
1个回答

2
您可以使用 ArraySegment<T> 结构体:
for (int i = 0; i < threadsArray.Length; i++)
{
    sub[i] = new ArraySegment<double>(full, i * 4, 4);

    ArraySegment<double> tempSub = sub[i];

    threadsArray[i] = new Thread(() => DoStuff(tempSub));
    threadsArray[i].Start(); 
}

(请注意,您需要更改DoStuff的签名,以接受ArraySegment<double>(或至少是IList<double>而不是数组)

ArraySegment<T>不会复制数据;它只表示数组的一个段,通过保留对原始数组的引用、偏移量和计数。自.NET 4.5以来,它实现了IList<T>,这意味着您可以在不担心操作偏移量和计数的情况下使用它。

在.NET 4.5之前,您可以创建一个扩展方法,以便轻松枚举ArraySegment<T>

public static IEnumerable<T> AsEnumerable<T>(this ArraySegment<T> segment)
{
    for (int i = 0; i < segment.Count; i++)
    {
        yield return segment.Array[segment.Offset + i];
    }
}

...

ArraySegment<double> segment = ...
foreach (double d in segment.AsEnumerable())
{
    ...
}

如果您需要通过索引访问项目,则需要创建一个实现IList<T>的包装器。这里是一个简单的实现:http://pastebin.com/cRcpBemQ


谢谢,但不幸的是我使用的是.NET 4.0,所以如果我使用它,我还需要通过传递来跟踪偏移量吗? - Frayed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接