在C#中将子数组作为引用

我有大量函数以只读方式接受子数组的输入(比方说,字符串)。

我使用Array.Copy (C ++ memmove等效于MSDN)作为临时解决方法,但它在运行速度方面遇到了严重的瓶颈。 有没有任何函数我可以得到一个子数组,让我们说[4~94]在[0~99]内,这样就可以传递给function x(array[])作为参考,其中x的内部数组是由[0~90]定义?

不幸的是,数组不能很好地进行分区。 获取子数组的唯一方法是创建原始数组的副本,这可能是瓶颈所在。

如果你可以修改你的函数来获取IEnumerable参数而不是数组,你可以使用LINQ轻松完成:

 string[] values = { "foo", "bar", "baz", "zap" }; IEnumerable subset = values.Skip(1).Take(2); 

您也可以查看ArraySegment ,但这会(再次)需要更改函数的参数类型。

 string[] values = { "foo", "bar", "baz", "zap" }; ArraySegment segment = new ArraySegment(values, 1, 2); 

在C#中没有内置的支持。 您可以通过引用传递数组中的单个元素,但不能传递数组段的地址,然后可以在托管代码中将其解释为基于0的数组。

显而易见的解决方案是将偏移量和长度与数组一起传递。 通过将数组包装在为您封装的IReadOnlyList实现中,您可以IReadOnlyList这种IReadOnlyList 。 例如:

 class SubsetList : IReadOnlyList { private readonly IReadOnlyList _list; private readonly int _offset = offset; private readonly int _length = length; public SubsetList(IReadOnlyList list, int offset, int length) { _list = list; _offset = offset; _length = length; } public int Count { get { return _length; } } public T this[int index] { get { return _list[offset + index]; } } public IEnumerator GetEnumerator() { for (int i = _offset; i < _offset + _length; i++) { yield return _list[i]; } } private IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 

请注意,上面并不是真正需要的,因为事实certificate.NET已经(并且已经有.NET 2.0)的ArraySegment结构,它完成了上述和更多。 但是在.NET 4.0之前,它似乎没有实现使其透明使用的function(例如接口实现和索引器)。

所以我提供上述内容作为那些受限制的人的替代方案。 请注意, IReadOnlyList本身是.NET 4.5的新手,因此要将上述版本与.NET的先前版本一起使用,请将其更改为IList ,然后使用简单的throw new NotSupportedException()实现该接口的所有其他成员throw new NotSupportedException() (可能是索引器的setter除外)。