2016-08-04 2 views
1

Скажем, у меня есть следующий код:распределения вороха при прохождении мимо исм и инстанцирование нового объекта

var person = new Person(); 
Manipulate(ref person); 

И следующий метод:

public void Manipulate(ref Person pObject) 
{ 
    pObject = new Person(); 
} 

делает метод Manipulate, когда инстанцировании новый человек объект, указать на то же место в куче и создать объект pObject в этом месте или создать новое место в куче?

ответ

2

Ответ в Docs:

Место хранения объекта передается методу в качестве значения опорного параметра. Если вы измените значение в ячейке хранения параметра (чтобы указать на новый объект), вы также можете изменить местоположение хранилища, на которое ссылается вызывающий. .

Для того, чтобы понять, проверьте приведенный ниже пример:

static int[] array = new int[] { 5 }; 

static void Main(string[] args) 
{ 
    var array2 = array; 
    ModifyRef(ref array2); 

    foreach (var item in array) 
     Console.WriteLine(item); 
    foreach (var item in array2) 
     Console.WriteLine(item); 
} 

private static void ModifyRef(ref int[] array) 
{ 
    array = new int[1]; 
    array[0] = 10; 
} 

распечаток:

5 
10 

Создание указатель передается по ссылке относятся к новому объекту не означает, что старый объект заменяется. array2 теперь указывает на новое местоположение памяти, но array все еще указывает на тот же старый массив в памяти.

+0

'static int [] array = {5};': | – Will

+0

Спасибо, это делает вещи более ясными. –

2

В некоторых сценариях нет смысла создавать объект в том же месте памяти. Если это произошло, то следующий код не будет работать так, как это делает:

public class Program 
{ 
    static void Main(string[] args) 
    { 
     var x = new Person("Old name"); 
     var y = x; 
     M(ref x); 
     Console.WriteLine(y.Name); // Prints "Old name" 

     Console.ReadKey(); 
    } 

    static void M(ref Person person) 
    { 
     person = new Person("New name"); 
    } 
} 

class Person 
{ 
    public string Name { get; } 

    public Person(string name) 
    { 
     Name = name; 
    } 
} 

старый объект с Old name значения свойства больше не существует, так что вы не могли видеть Old name распечатаны. Поскольку вы видите это, два разных объекта существуют одновременно.

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