C#: method with ref-to-object argument declared

G

Guest

Guys, I 've met some strange behaviour of the C# compiler. To reproduce it
please try to compile the code below and you 'll be really amazed. The
problem is that you can not use an interface pointer variable as a
ref-to-object parameter.

interface IMy
{
void f();
}

public class My : IMy
{
public void f()
{
}

public static void Main(string[] args)
{
IMy val = null;
System.Threading.Interlocked.CompareExchange(ref val, new My(), null);
}
}
 
N

Nicholas Paldino [.NET/C# MVP]

Alexander,

It's not surprizing at all. ref arguments must match exactly,
otherwise, you could do this:

void DoSomething(ref object o)
{
o = 1;
}

// Call do something with a string.
string s = "Hello";

// Make the call.
DoSomething(ref s);

Allowing this kind of behavior would be very, very bad.

Hope this helps.
 
J

Jon Skeet [C# MVP]

<=?Utf-8?B?QWxleGFuZGVyIEZlZGlu?= <Alexander
Guys, I 've met some strange behaviour of the C# compiler. To reproduce it
please try to compile the code below and you 'll be really amazed. The
problem is that you can not use an interface pointer variable as a
ref-to-object parameter.

I won't be amazed at all, having read the spec, which states:

(Section 14.4.2.1, ECMA spec)

<quote>
A function member is said to be an applicable function member with
respect to an argument list A when all of the following are true:

* The number of arguments in A is identical to the number of
parameters in the function member declaration.
* For each argument in A, the parameter passing mode of the
argument (i.e., value, ref, or out) is identical to the parameter
passing mode of the corresponding parameter, and
o for a value parameter or a parameter array, an implicit
conversion (§13.1) exists from the type of the argument to the type of
the corresponding parameter, or
o for a ref or out parameter, the type of the argument is
identical to the type of the corresponding parameter.
</quote>

Note the last part.

This shouldn't be surprising at all though. Consider the following
code, based on yours:

interface IMy
{
void f();
}

public class My : IMy
{
public void f()
{
}

static void DoSomething (ref object o)
{
o = "hello";
}

public static void Main(string[] args)
{
IMy val = null;
DoSomething(ref val);
}
}

If this were to compile, it would be horrible - either a runtime
exception would have to occur, or you'd end up with val being a
reference to something which *isn't* an IMy.

Note that this has nothing to do with interfaces per se - the same
would have been true if you'd not had an IMy interface at all, and just
used My val = null; instead.
 

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