【问题标题】:Function error for List<String>: 'a property or indexer may not be passed as an out or ref parameter'List<String> 的函数错误:'属性或索引器不能作为 out 或 ref 参数传递'
【发布时间】:2019-07-23 19:08:03
【问题描述】:

我尝试设置一个动态代码来检查系统中有多少个内核。我想我已经正确设置了它,我为每个核心启动一个任务,然后等待所有任务完成。

现在可以看出,每个任务将返回“list1[i]”和“list2[i]”,如下所示:

out list1[i], out list2[i]

但是上面显示了这个错误:

“属性或索引器不能作为 out 或 ref 参数传递”

我已经从我编写的其他代码中意识到了这个问题,无法返回到这样的索引中。

当我尝试编写考虑系统中有多少内核的动态代码时。如果系统有 24 个内核,怎么可能做我想做的事情,而不是拥有例如 24 个硬编码列表?

private void button1_Click(object sender, EventArgs e)
{
    new Thread(runthreads).Start();
}
void runthreads()
{
    int nrCores = Environment.ProcessorCount;
    List<List<String>> list1 = new List<List<String>>(); List<List<String>> completelist1 = new List<List<String>>();
    List<List<String>> list2 = new List<List<String>>(); List<List<String>> completelist2 = new List<List<String>>();
    Task[] tasks = new Task[nrCores];
    for (int i = 0; i < nrCores; i++)
    {
        //Add lists
        list1.Add(new List<String>());
        list2.Add(new List<String>());

        //Start Task
        tasks[i] = Task.Factory.StartNew(() => onefunction(1, 2, out list1[i], out list2[i]));
    }
    Task.WaitAll(tasks); //Wait for all Tasks to complete

    //Now add all lists to completelists
    for (int i = 0; i < list1.Count; i++)
    {
        completelist1.AddRange(list1[i]);
        completelist2.AddRange(list2[i]);
    }
}
void onefunction(int num1, int num2, out List<String> list1, out List<String> list2)
{
    //Example code for the function!
    list1 = new List<String>(); list2 = new List<String>();
    for (int i = 0; i < 1000000; i++)
    {
        list1.Add("1");
        list2.Add("2");
    }
}

【问题讨论】:

  • 你可以使用数组索引。您已经确切知道有多少项目,因此可以使用数组。即使这样,一个更简单的替代方法可能是将方法中的列表作为元组或类中的属性返回。
  • 这听起来是个好消息。当涉及到数组时,我很糟糕。我真的总是使用列表,如果数组是一个不错的选择,我不太确定如何声明它?
  • 我不明白你为什么需要out?为什么不在函数之外创建列表并让onefunction 填充它们?
  • 最简单的方法是让参数不再是out。调用者创建空列表,onefunction 填充它们。
  • ... =&gt; onefunction(1, 2, list1[i], list2[i])。从onefunction 参数声明中删除out,并从正文中删除list1 = new List&lt;String&gt;(); list2 = new List&lt;String&gt;();。最初创建所有这些列表然后将它们扔掉似乎毫无意义。使用它们!

标签: c#


【解决方案1】:

我尝试过使用数组的方法。有人可以确认这是一种有效的方法,或者如果我错过了什么或某事可以以更快的方式完成。

例如,如果这是最快的方式,或者这是一个瓶颈,因为速度很重要。我只能想到 do .ToArray() 但想知道这是否确实“双重”工作而不是通过直接添加到数组而不是从列表中转换来做一些更干净的事情? (请注意,稍后我将不知道要向数组中添加多少元素)

array1 = list1.ToArray();

完整代码:

        private void button1_Click(object sender, EventArgs e)
        {
            new Thread(runthreads).Start();
        }
        void runthreads()
        {
            int nrCores = Environment.ProcessorCount;
            String[][] array1 = new String[nrCores][];
            String[][] array2 = new String[nrCores][];

            List<String> completelist1 = new List<String>();
            List<String> completelist2 = new List<String>();
            Task[] tasks = new Task[nrCores];
            for (int i = 0; i < nrCores; i++)
            {
                //Start Task
                tasks[i] = Task.Factory.StartNew(() => onefunction(1, 2, out array1[i], out array2[i]));
            }
            Task.WaitAll(tasks); //Wait for all Tasks to complete

            //Now add all lists to completelists
            for (int i = 0; i < array1.Length; i++)
            {
                completelist1.AddRange(array1[i]);
                completelist2.AddRange(array2[i]);
            }
        }
        
        void onefunction(int num1, int num2, out String[] array1, out String[] array2)
        {
            //Example code for the function!
            List<String> list1 = new List<String>(); List<String> list2 = new List<String>();
            for (int i = 0; i < 1000000; i++)
            {
                list1.Add("1");
                list2.Add("2");
            }
            array1 = list1.ToArray();
            array2 = list2.ToArray();
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2020-11-26
    • 2012-07-30
    • 2011-06-16
    • 2012-09-08
    • 2011-09-23
    相关资源
    最近更新 更多