【发布时间】:2010-04-12 19:29:41
【问题描述】:
是否有一种简单的方法可以从现有字节数组的一部分初始化字节数组。在 C 语言中,可以使用指针来表示喜欢
char s[10] = new char[10];
char* b = s + 5;
是否可以在 c# 中做到这一点,例如:
byte[] b = new byte[buffersize];
byte* header = b + 5;
byte* data = b + 25;
【问题讨论】:
是否有一种简单的方法可以从现有字节数组的一部分初始化字节数组。在 C 语言中,可以使用指针来表示喜欢
char s[10] = new char[10];
char* b = s + 5;
是否可以在 c# 中做到这一点,例如:
byte[] b = new byte[buffersize];
byte* header = b + 5;
byte* data = b + 25;
【问题讨论】:
ArraySegment<T> 结构提供数组视图,无需创建副本。但是,它不能用于需要字节数组的地方。
ArraySegment<byte> myArraySegment = new ArraySegment<byte>(myArray, 2, 5);
如果需要字节数组,则需要将所需的值复制到新的数组实例中,最好使用Buffer.BlockCopy:
byte[] newArray = new byte[5];
Buffer.BlockCopy(myArray, 2, newArray, 0, 5);
【讨论】:
这是可能的,但它需要不安全的代码:
unsafe
{
byte[] b = new byte[buffersize];
fixed(byte* bStart = b)
{
byte* header = bStart + 5;
byte* data = bStart + 25;
}
}
话虽如此,除非在 C# 中绝对必要,否则通常会避免这种情况。使用不安全的代码不是常态,因为正如建议的那样,它是不安全的。这种类型的代码会导致很多错误,因此最好重新考虑设计。
【讨论】:
当然有。
int[] myArray = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] subArray = myArray.Skip(5).ToArray();
性能特征与您的 C 示例非常不同,但它们确实并不糟糕。如果您正在寻找性能,而不是像上面那样使用 unsafe,请使用相同的数组并简单地从列表中您想要的点开始迭代,或者使用 Array.Copy,如其他地方所示。
【讨论】:
var arrOld = new byte[] { 0, 1, 2, 3, 5 };
int buffersize = 10;
var arrNew = new byte[buffersize];
Array.Copy(arrOld, arrNew, arrOld.Length);
【讨论】:
您需要在 C# 中使用不安全代码,这需要您在构建设置中选中“允许不安全代码”选项。
unsafe
{
byte[] b = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
fixed (byte* pStart = b)
{
byte* pHeader = pStart + 2;
byte* pData = pStart + 5;
}
}
【讨论】:
要小心:你的 C 代码只有 一个 数组。您的另一个数组实际上只是原始视图。如果你真的想要两个数组,你可以使用Array.Copy(),像这样:
char[] s = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'};
char[] b = new char[5];
Array.Copy(s, 6, b, 0, 5);
还值得一提的是,在 c# 中,字符和字节是 非常 不同的东西。不要混淆他们,否则你会发现自己有麻烦。此外,数组很少是 C# 中的最佳选择。改用一个类、一个泛型 List,甚至只是一个 IEumerable。
【讨论】: