Проходя мимо 'ref' - c # - PullRequest
       5

Проходя мимо 'ref' - c #

4 голосов
/ 16 июня 2011

К моему ужасу, следующий код не скомпилируется.

Однако он скомпилируется, если я удалю ключевое слово ref.

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

    static void bar()
    {
        string bbb="";
        foo(ref bbb);
        //foo(ref (object)bbb); also doesnt work
    }
}
  1. Может кто-нибудь объяснить это? Я догадываюсь это как-то связано с реф быть очень строгим с производным классы.

  2. Есть ли способ, которым я могу передать объект типа строка в foo(ref object varname)?

Ответы [ 4 ]

8 голосов
/ 16 июня 2011

Это должно быть точное совпадение, иначе foo может сделать:

aaa = 123;

, который будет действителен для foo (это будет int к object),но не для bar (где это string).

Два немедленных варианта;во-первых, используйте промежуточную переменную и проверку типа:

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

или, в качестве альтернативы, возможно, попробуйте дженерики (foo<T>(ref T aaa));или трактуйте bbb как object вместо string.

5 голосов
/ 16 июня 2011

Нет, нет.Представьте себе следующее:

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

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

Foo попытается присвоить SomeObject переменной, которая на самом деле string!

0 голосов
/ 16 июня 2011

Вы должны использовать точно такой же тип.Вы можете использовать преимущество 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
}
0 голосов
/ 16 июня 2011

Когда вы передаете varaible по ссылке, он должен точно соответствовать типу.

Вы можете вызвать метод, создав другое varaible с правильным типом:

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

Если выЧтобы вернуть измененное значение обратно в строковую переменную, вы должны проверить тип и привести его:

bbb = o as string;

Попробуйте использовать возвращаемое значение вместо ключевого слова ref и просто вернуть измененноезначение:

static object foo(object aaa) {

Использование:

o = foo(o);
...