我正在尝试从现有数组中获取子数组的引用。 我希望能够在子阵列上进行修改时更新原始数组。 示例:
byte[] array = {0 , 1, 2, 3, 4};
byte[] subarray = array.Skip(2).Take(3).ToArray();
subarray[0] = 8;
Console.WriteLine("array[2] = " + array[2]);
我想看看:
array [2] = 8
但相反,我得到:
array [2] = 2
我读了这个solution,但它不够好,因为我不想给出修改不在范围内的数组值的选项,如下所示:
ArraySegment<byte> segment = new ArraySegment<byte>(array, 2, 3);
byte[] segmentByte = segment.ToArray();
我可以通过segmentByte
修改所有原始数组。这就是我想要阻止的。
答案 0 :(得分:3)
您可以编写简单的Array
和ArraySegment<of T>
包装器,仅提供一组必需的操作:
struct StrictRangeArraySegment<T>
{
ArraySegment<T> _segment;
public StrictRangeArraySegment(T[] array)
: this(array, 0, array.Length)
{
}
public StrictRangeArraySegment(T[] array, int offset, int count)
: this(new ArraySegment<T>(array, offset, count))
{
}
public StrictRangeArraySegment(ArraySegment<T> segment)
{
_segment = segment;
}
public int Count
{
get
{
return _segment.Count;
}
}
public T this[int index]
{
get
{
if (index < 0 || index >= _segment.Count)
throw new ArgumentOutOfRangeException(nameof(index));
return _segment.Array[_segment.Offset + index];
}
set
{
if (index < 0 || index >= _segment.Count)
throw new ArgumentOutOfRangeException(nameof(index));
_segment.Array[_segment.Offset + index] = value;
}
}
}
有关参考,请参阅ArraySegment<Of T>
source code。
答案 1 :(得分:0)
如果仔细查看ToList
方法,您会看到它完全生成一个新列表,而这个列表根本不会引用旧列表。因此,您更改的内容仅反映为subarray
。
唯一的解决方案是使用您不想要的ArraySegment
。
public List<TResult> ToList()
{
var list = new List<TResult>();
foreach (TSource item in _source)
{
list.Add(_selector(item));
}
return list;
}
答案 2 :(得分:0)
一个选项是创建一个类型,将整数作为对象的属性包装。然后更新属性将得到所需的结果:
public class Box<T>
{
public T Value {get;set;}
public Box<T>(T item) {Value = item;}
}
Box<byte>[] array = {new Box<byte>(0), new Box<byte>(1), new Box<byte>(2), new Box<byte>(3), new Box<byte>(4)};
Box<byte>[] subarray = array.Skip(2).Take(3).ToArray();
subarray[0].Value = 8;
Console.WriteLine("array[2] = " + array[2].Value);
//you'll see "8" instead of "2" now
您可能还想查看Span<T>
。它还没有完全发布,但它可能会在这里实现你的目标。