不清楚你想要什么,但我猜你想要一个字节数组的“视图”。在 .Net 4.5 中,您可以这样做ArraySegment<T>
:
var a = new byte[100];
var s = new ArraySegment<Byte>(a, 9, 90);
((IList<Byte>)s)[0] = 10;
Console.WriteLine(a[9]); // writes "10"
因此,您的Write90Bytes
方法可以返回一个ArraySegment<Byte>
,然后您可以将其作为底层数组的视图进行操作,这将避免复制。但是请注意,这ArraySegment<T>
是 a System.ValueType
,这意味着将其转换为IList<T>
将招致拳击惩罚。
如果性能至关重要并且您需要避免复制,您还可以考虑在不安全的上下文中使用指针,这意味着您的Write90Bytes
方法可以返回 aByte*
并且您可以通过这种方式索引到数组中。
编辑:现在我看到了您的编辑,您不能只将函数中的值“返回”到数组的内存位置。您需要将原始数组作为参数传递。
编辑2:你不能做你所要求的。该ComputeHash
函数返回一个它自己分配的数组。你可以做你想做的唯一方法是ComputeHash
将数组作为参数。考虑:
// previously defined...
byte[] bigTargetBytes = new byte[10000];
// This method doesn't really exist, but if it did it would look like this
sha256.ComputeHash(sourcebytes, bigTargetBytes, offset);
尽管在 .Net 中,由于它是托管运行时,因此对内存分配有特定的限制,但这是任何编程语言中的常见模式。在 C/C++ 开发中,有一个协议使用,您可以传入一个预分配的数组,其中包含要写入的偏移量和最大长度,或者您允许函数返回分配的内存,然后您有责任释放 (除非您从框架中被回调)。您不能只将值返回到现有缓冲区中。
但是请注意,仅从由该ComputeHash
值分配的 GC 数组中复制 20 个字节是一个非常简单的操作,运行时可以非常有效地处理它。除非您不时对微秒级暂停非常敏感,否则您不会注意到实际副本和假设实现之间的差异。