Reputation: 8736
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.
Upvotes: 7
Views: 1376
Reputation: 1627
by not allowing the function with ref along with parameter type, the compiler is actually preventing to have compromise with type safety. The same happens in the following scenario as well
private static void MyMethod(out object MyPara)
{
MyPara = new String('x', 10);
}
MyClass obj = new MyClass();
MyMethod(out obj); //compile time error
Compiler is actually keeping the memory location of obj safe by not allowing this scenario to compile. If this would have been allowed security of the application can be easily compromised
Upvotes: 0
Reputation: 44439
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.
Upvotes: 7
Reputation: 65244
Type inference is smart, but it is unable to read your mind. So just declaring var b = new { };
is simply not enough information to make the compiler understand, that you want something, that can be ref-passed as an Object.
var b = new Object ();
Bar (ref b);
will work ofcourse.
Upvotes: -1
Reputation: 134801
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;
}
Upvotes: 5