Why isn't implicit casting allowed on OUT parameters?

  • Thread starter Thread starter Yurik
  • Start date Start date
Y

Yurik

A question to the C# language experts: Why isn't this code valid?

static void Foo( out string s )
{
s = "test";
}

static void Main( )
{
object s; // *** Accept any out type!
Foo( out s );
}

If s is uninitialized at the beginning of Foo, what difference does it
make what type the out value will eventually be assigned to, when the
function finally exits?

Thanks!
 
Hi Yurik,

The point here is, you cannot pass object into the method that explicity
expects string.
 
Hi Yurik,

I am not a language expert, but I think it has to do with the fact that
the compiler needs to know if the output parameter is a value
(stack-based) type, or a reference (heap-based) type.

This is from the C# specification:

<quote>
1. An output parameter does not create a new storage location. 2
Instead, an output parameter represents the same storage location as the
variable given as the argument in the function member invocation. 3
Thus, the value of an output parameter is always the same as the
underlying variable.
</quote>

If you declare your output parameter as an "object" type, the compiler
does not have enough information on the storage semantics of the parameter.

Regards,

Bennie Haelen
 
SevDer said:
The point here is, you cannot pass object into the method that explicity
expects string.

But no data is actually being passed in - just the address of the
variable, effectively. If C# were the only language in the framework, I
don't think this would be a problem...
 
Yurik said:
A question to the C# language experts: Why isn't this code valid?

static void Foo( out string s )
{
s = "test";
}

static void Main( )
{
object s; // *** Accept any out type!
Foo( out s );
}

If s is uninitialized at the beginning of Foo, what difference does it
make what type the out value will eventually be assigned to, when the
function finally exits?

I *suspect* the problem is that not all languages actually support
"out" in the same way - it's possible that some *will* use the value of
the variable before assigning to it. I know from my work on
EasyMock.NET that the current value of a variable which is passed as an
out parameter *is* actually available at run time, if you're using
RealProxy. I suspect that to get type safety absolutely secure, it's
easier to assert that the type is exactly right in C#.
 
But no data is actually being passed in - just the address of the
variable, effectively. If C# were the only language in the framework, I
don't think this would be a problem...

Isn't there is still a problem with structs (by-value), the caller would
need to allocate the correct amount of space for the struct, or shall
the code that does assignment to structs as out parameters do checking
of the "dynamic-type" of the out parameter and boxing when required?
 
Helge Jensen said:
Isn't there is still a problem with structs (by-value), the caller would
need to allocate the correct amount of space for the struct, or shall
the code that does assignment to structs as out parameters do checking
of the "dynamic-type" of the out parameter and boxing when required?

Yes, it wouldn't work for value types - but it certainly would work in
the case presented in this thread.
 
I still fail to see any major distinction between an out parameter and
a method return type. Isn't out param simply an additional return
value? In which case, why should the callee worry about the type the
return value will be assigned to? The caller should do all the
appropriate casting (IMHO).

Is OUT parameter supported on the C# or on IL level?

Thanks!
 
Yurik said:
I still fail to see any major distinction between an out parameter and
a method return type. Isn't out param simply an additional return
value? In which case, why should the callee worry about the type the
return value will be assigned to? The caller should do all the
appropriate casting (IMHO).

Is OUT parameter supported on the C# or on IL level?

A bit of both, actually. The runtime defines the out parameter flag, but
does not enforce semantics. The particluar semantics are up to the language.
 
Yurik said:
I still fail to see any major distinction between an out parameter and
a method return type. Isn't out param simply an additional return
value? In which case, why should the callee worry about the type the
return value will be assigned to? The caller should do all the
appropriate casting (IMHO).

Is OUT parameter supported on the C# or on IL level?

I've worked out one potential reason why it has to be the same type.
Consider the following situation:

using System;
using System.Threading;

public class Test
{
object member;

void Foo(out object o)
{
o = "hello";

Thread.Sleep(1000);

Console.WriteLine (o);
}

void SetMemberToThis()
{
Thread.Sleep(500);
member = this;
}

Test()
{
new Thread (new ThreadStart(SetMemberToThis)).Start();
Foo(out member);
}

static void Main()
{
new Test();
}
}


That's fine, but imagine if you changed Foo to be:

void Foo(out string o)
{
o = "hello";

Thread.Sleep(1000);

string x = o;
}

What value would x and o have? Both would be non-strings by the end of
the method...
 
Back
Top