C# объект передается по ссылке или по значению

Вывод следующего кода меня удивил. Я думаю, что "а" должен содержать ссылку на вновь созданный объект. Может кто-нибудь объяснить, почему результат не 2?

class Program
{
    static void Main(string[] args)
    {
        aclass a = new aclass();
        Process(a);
        Console.WriteLine(a.number);

        Console.ReadLine();
    }

    static void Process(aclass a)
    {
        aclass temp = new aclass();
        temp.number++;
        //Console.WriteLine(temp.number);

        a = temp;
        a.number++;
        //Console.WriteLine(a.number);
    }

}

class aclass
{
    public int number = 0;
}

Изменить: это вопрос интервью. Я только что понял, что неправильно понял концепцию в течение долгого времени. Аргумент a отличается от оригинала a, хотя они ссылаются на один и тот же адрес.

3 ответа

Решение

Вы не изменяете фактическую исходную ссылку, вы просто изменяете ссылку, содержащуюся в параметре, что не совсем то же самое, изменения не сохраняются обратно к вызывающей стороне. Вы можете изменить это поведение, используя out или же ref,

В этом случае конкретно вы хотели бы использовать ref как вы также передаете ссылку в.

Пытаться:

class Program
{
    static void Main(string[] args)
    {
        aclass a = new aclass();
        Process(ref a);
        Console.WriteLine(a.number);

        Console.ReadLine();
    }

    static void Process(ref aclass a)
    {
        aclass temp = new aclass();
        temp.number++;
        //Console.WriteLine(temp.number);

        a = temp;
        a.number++;
        //Console.WriteLine(a.number);
    }

}

Помните, что вы назначаете совершенно новую ссылку a = temp, Если вы просто хотите обновить существующий класс, который вы изначально передали, то вы можете сделать:

a.number = temp.number;
a.number++;

Это сведет на нет необходимость ref,

Вы можете прочитать больше на MSDN:

Передача параметров типа ссылки

ref Ключевое слово

Ключевое слово

Эта линия aclass a = new aclass(); создает переменную (пространство, где мы можем хранить данные) в памяти. Учтите, что его адрес в памяти *(0x12DF) и value который хранится в этом месте является объектом a

Эта линия Process(a) проходит VALUE объекта a НЕ АДРЕС, чтобы функционировать Processтак что-нибудь происходит в Process() не имеет ничего общего с contents местоположения *(0x12DF)так что содержимое локации *(0x12DF) останется таким же, как было до звонка Process(),

СОДЕРЖАНИЕ *(0x12DF) = а

Я надеюсь, что это полезно, а не создавать больше путаницы!

Это в основном разница между

  • Передача ссылочных типов по значению // Process(a);
  • Передача ссылочных типов по ссылкам // Process(ref a);

В этом примере Process(a) - "a", который является ссылочным типом, передается методу без параметра ref. В таком случае копия ссылки, которая указывает на a, передается методу.

Выделение новой части памяти с помощью оператора new внутри метода Process делает переменную 'a' ссылкой на новый объект класса. Таким образом, любые изменения после этого не будут влиять на исходный объект "а".

См. MSDN: http://msdn.microsoft.com/en-us/library/s6938f28.aspx

Другие вопросы по тегам