Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass an anonymous object into a method that expects a reference parameter of type object?

I'd like to know why the first call to Bar(ref object) doesn't work and the second one does. Seems silly considering I'm passing in a type object either way, and passing in an anonymous type to Foo(object) works fine. Why would ref, something that has to do with memory location influence the calls to Bar()?

Consider the following snippet:

static void Foo(object obj)
{ }

static void Bar(ref object obj)
{ }

static void Main()
{
    // Compiles
    var a = new { };
    Foo(a);

    // Does not compile
    var b = new { };
    Bar(ref b);

    // Compiles
    object c = new { };
    Bar(ref c);
}

I see in the answers below suggestions on how to make the code compile, but that's not what I'm after. I'd like to know specifically why making it a ref parameter prevents compilation when passing in an anonymous type to Foo() worked fine.

like image 962
Didaxis Avatar asked Feb 19 '15 01:02

Didaxis


2 Answers

The main reason is a little hidden: this happens because your passed in argument has to be the exact same type as the type defined in the parameter.

This is (ambiguously?) stated in the specification section $10.6.1.2:

When a formal parameter is a reference parameter, the corresponding argument in a method invocation must consist of the keyword ref followed by a variable-reference (§5.3.3) of the same type as the formal parameter.

For this very same reason, passing a subclass to a method that uses a reference parameter doesn't work. This is described in Jeff Mercado's answer.

In your first example you don't use ref so polymorphism works (an anonymous type is a subtype of object) and in the last example you declare it as object which means you use the exact same type as the reference parameter.

like image 95
Jeroen Vannevel Avatar answered Sep 21 '22 06:09

Jeroen Vannevel


Why should it? The variable b is not declared as an object as is expected by the method.

Consider this example:

string s;
GetValue(ref s); // no...

void GetValue(ref object x)
{
    x = 123;
}
like image 25
Jeff Mercado Avatar answered Sep 20 '22 06:09

Jeff Mercado