简体   繁体   中英

List<T> as 'out' parameter causes an error. Why?

In this code:

public bool SomeMethod(out List<Task> tasks)
{
    var task = Task.Factory.StartNew(() => Process.Start(info));
    tasks.Add(task);
}

I get an error, "Use of unassigned out parameter 'tasks'" . Why?

In an MSDN example there's just use of out parameter

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }

    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}

Is it because of List<T> ?

You have to initialize the out parameter in the method body (that is create a new List<Task> instance and assign it to the out parameter):

public bool SomeMethod(out List<Task> tasks) {
  var task = Task.Factory.StartNew(() => Process.Start(info);
  tasks = new List<Task>() { task };
  ...
}

I'm using the collection initializer syntax to add the task to the list, but you could call the Add method instead if you prefer.

You should call the method like this:

List<Task> tasks;
SomeMethod(out tasks);
var newTask = tasks[0]; // Access the task just created.

C# 7.0 has introduced new simpler syntax where you declare the variable in the call to the function with the out parameter:

SomeMethod(out var tasks);
var newTask = tasks[0]; // Access the task just created.

As a List<T> is passed by reference you can get rid of the out parameter. You then have to create the list before calling the method:

public bool SomeMethod(List<Task> tasks) {
  var task = Task.Factory.StartNew(() => Process.Start(info);
  tasks.Add(task);
  ...
}

And call it like this:

var tasks = new List<Task>();
SomeMethod(tasks);
var newTask = tasks[0]; // Access the task just created.

In general it is good practice to avoid out parameters because they can be confusing.

out means that your method needs to create the object, then assign it to the parameter:

List<Task> tasks = new List<Task>();
tasks.Add(task);

You need to do tasks = new List<Task>(); before you can add a Task object to it. MSDN has an example that is closer to what you're doing, this passes an array rather than an int.

It's because you didn't assign a value to the tasks -variable... in this case that would be a reference to a instance of type List<Task> .

Add tasks = new List<Task>(); to the body of SomeMethod and everything will work fine:

public bool SomeMethod(out List<Task> tasks) {
   tasks = new List<Task>();
   var task = Task.Factory.StartNew(() => Process.Start(info);
   tasks.Add(task);
}

You need to initialise the tasks parameter. eg tasks = new List<Task>()

This thread discusses the use of out and ref with parameters. If you use the ref keyword then you must have set the value prior to calling the method. I see no reason to use the ref keyword in this case though

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM