4

Much to my dismay, the follow code wont compile.

It will however compile if I remove the ref keyword.

class xyz
{
    static void foo(ref object aaa)
    {
    }

    static void bar()
    {
        string bbb="";
        foo(ref bbb);
        //foo(ref (object)bbb); also doesnt work
    }
}
  1. Can anyone explain this? Im guessing it has something to do with ref's being very strict with derived classes.

  2. Is there any way I can pass an object of type string to foo(ref object varname)?

maxp
  • 24,209
  • 39
  • 123
  • 201
  • 2
    Note; if you are only passing the string *in*, you don't need `ref` here *anyway*; you ***only*** need `ref` here if `foo` is going to *reassign* `aaa`, ***and*** the caller needs to know about the reassignment. – Marc Gravell Jun 16 '11 at 12:26
  • 1
    This is a duplicate of http://stackoverflow.com/questions/1207144/c-why-doesnt-ref-and-out-support-polymorphism/1207302#1207302 – Eric Lippert Jun 16 '11 at 13:36

4 Answers4

8

It has to be an exact match, else foo could do:

aaa = 123;

which would be valid for foo (it will box the int to an object), but not for bar (where it is a string).

Two immediate options; firstly, use an intermediate variable and a type-check:

object tmp = bbb;
foo(ref tmp);
bbb = (string)tmp;

or alternatively, maybe try generics (foo<T>(ref T aaa)); or treat bbb as object instead of string.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
5

No, there isn't. Imagine the following:

static void Foo(ref object obj)
{
    obj = new SomeObject();
}

static void Bar()
{
    string s = "";
    Foo(ref s);
}

Foo would try to assign a SomeObject to a variable that's actually a string!

Sven
  • 21,903
  • 4
  • 56
  • 63
0

When you pass a varaible by reference, it has to match the type exactly.

You can call the method by creating another varaible with the correct type:

string bbb = "";
object o = bbb;
foo(ref o);

If you want the changed value back in the string variable, you have to check the type and cast it:

bbb = o as string;

Consider using a return value instead of the ref keyword, and just return the changed value:

static object foo(object aaa) {

Usage:

o = foo(o);
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

You have to use the exact same type. You can use advantage of dynamic

public static void foo(ref object a)
{
    a = "foo";
}

static void Main(string[] args)
{
    string bbb = "";
    dynamic a = bbb;        // or object
    foo(ref a);
    bbb = a;                // if it was object you need to cast to string

    Console.WriteLine(bbb); // foo
}
BrunoLM
  • 97,872
  • 84
  • 296
  • 452