Passing an out parameter

D

Dave Veeneman

Can I pass a method pass one of its out parameters to another method? C# is
telling me I can't.

Let's say I have two methods, FooManager and FooWorker. FooManager is part
of a class that acts as a coordinator for several other classes. FooManager
basically passes its parameters, including an output parameter 'x', on to
FooWorker, a worker method in another class. FooWorker does the actual work
and assigns to x. When FooWorker is done, it returns to FooManager, which
returns to the caller. It looks like this:

public object FooManager(object a, object b, out object x)
{
... (do some work)...

object result = FooWorker(a, b, out x);
return result;
}

Here's my problem: The C# compiler is throwing this compile-time error: "The
out parameter 'dictionary' must be assigned to before control leaves the
current method." I understand what it's saying-- it wants me to do something
with op before I send it to FooWorker. And from that it sounds like I can't
pass out parameters along from coordinator objects to worker objects.

Is there any way to pass an out parameter in the manner I've described? I'm
stuck with using an out parameter, for reasons I won't go into. Besides, I'm
out of aspirin...

Thanks for your help.
 
D

Dave Veeneman

I think I can solve the problem by passing x as a 'ref' parameter, instead
of as an 'out' parameter. Any thoughts? Thanks.
 
G

Guest

Just an idea, if you have not tried it (also did you try
to use ref instead of out?)

public object FooManager(object a, object b, out object x)
{
... (do some work)...
object y;

object result = FooWorker(a, b, out y);
x = y;
return result;
}
 
J

Jon Skeet [C# MVP]

Dave Veeneman said:
Can I pass a method pass one of its out parameters to another method? C# is
telling me I can't.

Let's say I have two methods, FooManager and FooWorker. FooManager is part
of a class that acts as a coordinator for several other classes. FooManager
basically passes its parameters, including an output parameter 'x', on to
FooWorker, a worker method in another class. FooWorker does the actual work
and assigns to x. When FooWorker is done, it returns to FooManager, which
returns to the caller. It looks like this:

public object FooManager(object a, object b, out object x)
{
... (do some work)...

object result = FooWorker(a, b, out x);
return result;
}

Here's my problem: The C# compiler is throwing this compile-time error: "The
out parameter 'dictionary' must be assigned to before control leaves the
current method." I understand what it's saying-- it wants me to do something
with op before I send it to FooWorker. And from that it sounds like I can't
pass out parameters along from coordinator objects to worker objects.

No, it's not saying that, but it's difficult to know *exactly* what
it's saying as none of the code that you've provided uses a variable
called "dictionary". Could you provide a short but *complete* example
which demonstrates the problem?
 
1

100

Hi Dave,

It works just fine. I think you misunderstand what the compiler told you.
The error means that you have to to give the *out* parameter value before
the excution leaves the method body. In your case that means that your
FooWorker method doesn't assign any value to x. You don't have to initialize
x before calling FooWorker. That is how *out* parameters works. And this is
one of the differences between *out* nad *ref* parameters. But you have to
give any *out* parameters value before method exits. That's why the compiler
won't tell you anything for FooManager because it knows that FooWorker will
give *x* value because *x* is passed as *out* parameter. So the problem is
in FooWorker. Check out FooWorker and make sure that you don't exit the body
before setting *x*. Of course it doesn't apply for the casses when you
terminate the method execution by throwing exception.

HTH
B\rgds
100
 
D

Dave Veeneman

The actual code was pretty complex-- It involved a collection manager
calling a factory method that returned an object for the collection. The
factory method also needed to update an object dictionary, which was passed
through several levels of the hierarchy. I figured nobody would want to wade
through all that stuff, so I tried to abstract away as much of the detail
from my question as I could.

In any event, switching from an 'out' parameter to a 'ref' parameter solved
the problem nicely. Thank you for your help.
 
J

Jon Skeet [C# MVP]

Dave Veeneman said:
The actual code was pretty complex-- It involved a collection manager
calling a factory method that returned an object for the collection. The
factory method also needed to update an object dictionary, which was passed
through several levels of the hierarchy. I figured nobody would want to wade
through all that stuff, so I tried to abstract away as much of the detail
from my question as I could.

In any event, switching from an 'out' parameter to a 'ref' parameter solved
the problem nicely. Thank you for your help.

It may have solved the compilation problem, but it *does* mean that
there's a return path which could return without the value being set -
this is likely to be a potential bug, and it's worth tracking it down.
 
C

Corey Kosak

The following code compiles without error for me. I
would guess that the problem you are having is that
somewhere else in your elided FooManager code you have an
early return from the routine where x has not been
definitely set.

class Test {
public object FooManager(object a, object b, out object
x) {
object result=FooWorker(a, b, out x);
return result;
}

public object FooWorker(object a, object b, out object
x) {
x=3;
return "hello";
}

static void Main(string[] args) {
}
}
 
1

100

Hi,
The other possibility for the error is that you give *x* value inside *if*
statement, in a *case* clause or inside a loop.
For example

public object FooWorker(object a, object b, out object x)
{
if(someCondition)
{
x = ....
}
-- OR --
siwtch(...)
{
case ... :
break;
case ... :
x = ...
break
......
}

--- OR ---

for(int i = 0; i < 10; i++)
{
x = ....
}
.....
}
}

In all cases above you'll have the compiler reporting the error.

HTH
B\rgds
100

Corey Kosak said:
The following code compiles without error for me. I
would guess that the problem you are having is that
somewhere else in your elided FooManager code you have an
early return from the routine where x has not been
definitely set.

class Test {
public object FooManager(object a, object b, out object
x) {
object result=FooWorker(a, b, out x);
return result;
}

public object FooWorker(object a, object b, out object
x) {
x=3;
return "hello";
}

static void Main(string[] args) {
}
}



-----Original Message-----
Can I pass a method pass one of its out parameters to another method? C# is
telling me I can't.

Let's say I have two methods, FooManager and FooWorker. FooManager is part
of a class that acts as a coordinator for several other classes. FooManager
basically passes its parameters, including an output parameter 'x', on to
FooWorker, a worker method in another class. FooWorker does the actual work
and assigns to x. When FooWorker is done, it returns to FooManager, which
returns to the caller. It looks like this:

public object FooManager(object a, object b, out object x)
{
... (do some work)...

object result = FooWorker(a, b, out x);
return result;
}

Here's my problem: The C# compiler is throwing this compile-time error: "The
out parameter 'dictionary' must be assigned to before control leaves the
current method." I understand what it's saying-- it wants me to do something
with op before I send it to FooWorker. And from that it sounds like I can't
pass out parameters along from coordinator objects to worker objects.

Is there any way to pass an out parameter in the manner I've described? I'm
stuck with using an out parameter, for reasons I won't go into. Besides, I'm
out of aspirin...

Thanks for your help.

--
Dave Veeneman
Chicago


.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top