Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从数组创建列表的效率_C#_Arrays_.net_List_Type Conversion - Fatal编程技术网

C# 从数组创建列表的效率

C# 从数组创建列表的效率,c#,arrays,.net,list,type-conversion,C#,Arrays,.net,List,Type Conversion,我需要从之前已经创建的数组开始创建一个列表,并且只会转换为列表。这样我就可以在不复制的情况下将数组应用到列表中,但是。我甚至能理解这样做的动机。但是,在某些情况下,我可以保证,除了从何处创建阵列之外,阵列没有也不会引用它 有没有办法使这种构造更有效,并在列表中内部使用数组?我知道如果我滥用它会有影响 最明显的例子是获取string.Split()的结果。如果您需要一个列表,唯一明显的解决方法就是进行此转换。目前,我还没有考虑编写一个直接拆分为列表的方法。据我所知,目前还没有正式的方法,但仍然可以

我需要从之前已经创建的数组开始创建一个列表,并且只会转换为列表。这样我就可以在不复制的情况下将数组应用到列表中,但是。我甚至能理解这样做的动机。但是,在某些情况下,我可以保证,除了从何处创建阵列之外,阵列没有也不会引用它

有没有办法使这种构造更有效,并在列表中内部使用数组?我知道如果我滥用它会有影响


最明显的例子是获取
string.Split()
的结果。如果您需要一个列表,唯一明显的解决方法就是进行此转换。目前,我还没有考虑编写一个直接拆分为列表的方法。

据我所知,目前还没有正式的方法,但仍然可以使用
System.Reflection
。通过查看
列表的源代码,.NET Framework 4.7.2,两个重要属性是
\u items
\u size
。还有
\u版本
,但只有当您修改
列表
时,该版本才会更改。修改包括
添加
添加范围
删除
等,但也包括
反向
排序
。因此,我们假设这与从
IEnumerable
创建列表的操作相同,其中
\u 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);
    }
}
公共静态类ListExtensions
{
公共静态void setUnderlineArray(此列表,T[]数组)
{
锁(列表)
{
SetInternalArray(列表,数组);
SetInternalArraySize(列表,array.Length);
}
}
私有静态void SetInternalArraySize(此列表,整数大小)
{
var prop=list.GetType().GetField(
“_大小”,
BindingFlags.NonPublic | BindingFlags.Instance);
属性设置值(列表、大小);
}
私有静态void SetInternalArray(此列表,T[]数组)
{
var prop=list.GetType().GetField(
“_项目”,
BindingFlags.NonPublic | BindingFlags.Instance);
属性设置值(列表、数组);
}
}
然后设置基础数组

int[] array = Enumerable.Repeat(1, 1000000).ToArray();
List<int> list = new List<int>();

list.SetUnderlyingArray(array);
int[]array=Enumerable.Repeat(110000).ToArray();
列表=新列表();
list.setUnderlineArray(数组);


注意此解决方案高度依赖于实现的细节,如果
列表
内部发生更改,则可能是错误的,但它提供了如何实现的见解。

如果您不特别需要
列表
,则可以创建一个实现
IList
的新类不复制。

请尝试:string.Split().ToList(),这样您就不会创建数组。@jdweng它会创建一个数组并转换为列表。是的,但不会创建变量。因此,在以后的代码中,您不必创建列表作为第二个变量。我认为您无法避免数组的副本。看。@jdweng我的问题不是变量,而是对象。我会试试看。我不想要这个解决方案,因为它依赖于细节。但这可能是唯一的选择。如果
\u项目
受到
保护
那就容易多了。我说过依赖性我意识到这一点,我也理解你的担忧……如果一切都失败了,这是一种选择,我想,这是一种激进的方式,但这是一种有效的方式。我要说,它没有反射方式那么激进。不依赖于
List
的实现是的,反射也是激进的