Man*_*ero 5 .net c# arrays list type-conversion
我需要从之前创建的数组开始创建一个列表,并且只会转换为列表.所以我可以在不制作副本的情况下将数组利用到列表中,但构造函数会复制.我甚至可以理解这个动机.但是有些情况我可以保证数组没有,除了创建它之外没有引用它.
有没有办法让这个结构更有效,并在列表内部使用数组?我知道如果我误用它会有影响.
最明显的例子就是得到一个结果string.Split().如果您需要一个列表,那么唯一明显的方法就是进行此转换.现在我不打算写一个方法直接拆分成一个列表.
据我所知,没有官方方法可以做到这一点,但仍然可以使用System.Reflection. 通过查看.NET Framework 4.7.2的源代码List<T>,两个重要的属性是_items和_size。还有_version一个,但只有当你修改时才会改变List<T>。修饰有Add、AddRange、Remove等,也Reverse有 和Sort。因此,我们假设这与从零IEnumerable<T>处创建列表的操作相同。_version
public static class ListExtensions
{
public static void SetUnderlyingArray<T>(this List<T> list, T[] array)
{
lock (list)
{
SetInternalArray(list, array);
SetInternalArraySize(list, array.Length);
}
}
private static void SetInternalArraySize<T>(this List<T> list, int size)
{
var prop = list.GetType().GetField(
"_size",
BindingFlags.NonPublic | BindingFlags.Instance);
prop.SetValue(list, size);
}
private static void SetInternalArray<T>(this List<T> list, T[] array)
{
var prop = list.GetType().GetField(
"_items",
BindingFlags.NonPublic | BindingFlags.Instance);
prop.SetValue(list, array);
}
}
Run Code Online (Sandbox Code Playgroud)
然后设置底层数组
int[] array = Enumerable.Repeat(1, 1000000).ToArray();
List<int> list = new List<int>();
list.SetUnderlyingArray(array);
Run Code Online (Sandbox Code Playgroud)
注意:此解决方案高度依赖于实现的细节,如果内部发生变化,则可能会出错List<T>,但它提供了有关如何完成该解决方案的见解。
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |