2024-04-14 06:00:02

c#中的数组片

你是怎么做到的?给定一个字节数组:

byte[] foo = new byte[4096];

我如何得到数组的前x字节作为一个单独的数组?(具体来说,我需要它作为一个IEnumerable<byte>)

这是用于使用Sockets的。我认为最简单的方法是数组切片,类似于perl语法:

@bar = @foo[0..40];

将前41个元素返回到@bar数组中。c#中是否有我遗漏的东西,或者有其他我应该做的事情?

LINQ对我来说是一个选择。NET 3.5),如果有帮助的话。


当前回答

下面是一个简单的扩展方法,它返回一个slice作为一个新数组:

public static T[] Slice<T>(this T[] arr, uint indexFrom, uint indexTo) {
    if (indexFrom > indexTo) {
        throw new ArgumentOutOfRangeException("indexFrom is bigger than indexTo!");
    }

    uint length = indexTo - indexFrom;
    T[] result = new T[length];
    Array.Copy(arr, indexFrom, result, 0, length);

    return result;
}

然后你可以这样使用它:

byte[] slice = foo.Slice(0, 40);

其他回答

您可以使用Take扩展方法

var array = new byte[] {1, 2, 3, 4};
var firstTwoItems = array.Take(2);

如果你想要IEnumerable<byte>,那么只是

IEnumerable<byte> data = foo.Take(x);
byte[] foo = new byte[4096]; 

byte[] bar = foo.Take(40).ToArray();

下面是一个简单的扩展方法,它返回一个slice作为一个新数组:

public static T[] Slice<T>(this T[] arr, uint indexFrom, uint indexTo) {
    if (indexFrom > indexTo) {
        throw new ArgumentOutOfRangeException("indexFrom is bigger than indexTo!");
    }

    uint length = indexTo - indexFrom;
    T[] result = new T[length];
    Array.Copy(arr, indexFrom, result, 0, length);

    return result;
}

然后你可以这样使用它:

byte[] slice = foo.Slice(0, 40);

在c# 7.2中,您可以使用Span<T>。新制度的好处。内存系统的优点是它不需要到处复制数据。

你需要的方法是切片:

Span<byte> slice = foo.Slice(0, 40);

现在很多方法都支持Span和IReadOnlySpan,所以使用这个新类型非常简单。

请注意,在撰写本文时,Span<T>类型在。net的最新版本(4.7.1)中还没有定义,因此要使用它,您需要安装系统。来自NuGet的内存包。