【发布时间】:2010-10-10 00:00:13
【问题描述】:
如果我创建了一个字节数组 byte[] binBuffer = new byte[256] 并且我填充了数组的 100 个字节,如果我只想将这 100 个字节传递给其他方法,是否可以这样做不创建一个 100 字节的新字节数组,从旧数组复制到新数组,然后传递新数组?是否有某种方式我可以通过前 100 个字节。我的应用程序特别适用于将数组传递给存储过程。
【问题讨论】:
如果我创建了一个字节数组 byte[] binBuffer = new byte[256] 并且我填充了数组的 100 个字节,如果我只想将这 100 个字节传递给其他方法,是否可以这样做不创建一个 100 字节的新字节数组,从旧数组复制到新数组,然后传递新数组?是否有某种方式我可以通过前 100 个字节。我的应用程序特别适用于将数组传递给存储过程。
【问题讨论】:
如果你可以使用 linq:
SomeMethod(binBuffer.Take(100));
【讨论】:
如果您使用的是 .net 3.5,您可以使用 Take() 扩展方法并执行以下操作:
class Program
{
static void Main(string[] args)
{
byte[] b = new byte[1000];
dowork(b.Take(10).ToArray());
}
public static void dowork(byte[] b)
{
// do some work
}
}
【讨论】:
Take() 肯定会这样做。
将数组传递给方法时,实际上只传递了对它的引用,因为数组实际上是引用类型。你基本上有一个指向数组的指针,然后方括号中的偏移量只是告诉你距离开始有多少“槽”。因此,唯一真正的方法是将两个参数传递给您的方法。一个是实际数组,第二个是最大数量,直到你需要去的地方,在你的情况下它将是 100。在这种方法中,你只遍历数组直到达到最大数量。
【讨论】:
使用缓冲区时非常常见的模式是:
Foo(byte[] data, int offset, int count) {...}
模式。但是,您不能将其与 SqlCommand / 参数一起使用,因为当您分配给参数时,它会消耗整个缓冲区。您将需要一个新数组:
byte[] second = new byte[100];
Buffer.BlockCopy(first, firstOffset, second, 0, 100);
param.Value = second;
【讨论】:
简短的回答是:不。您所做的任何事情(除了将数组本身作为参数传递)都会创建一个新数组并复制其中的前 100 个字节。
但是,既然您不是按值传递数组,而是传递对它的引用,那么如果数组是 256 字节还是 100 字节,为什么对您很重要?你不会浪费更多的内存。不过,您可能需要告诉该方法要使用该数组的多少,因为 Length 方法将返回完整长度。
编辑:我刚刚意识到您想将数组传递给存储过程。这将复制整个数组。您必须仅使用要传递的元素制作副本。
【讨论】: