2015-05-10 3 views
1

Если у меня есть этот класс:Попутный varriables по ссылке

public class Foo 
{ 
    Boo a; 
    public Foo (ref Boo b) 
    { 
     a=b; 
    } 
} 

ли a будет ссылка на b или собирается скопировать значение, которое réf b очков? Если она копирует значение, как я могу сделать, что a ссылка на b и b ссылка на аргумент ссылки? (Как Java делает)

+0

Посмотрите на http://jonskeet.uk/csharp/parameters.html. – DWright

+2

В этом конкретном примере модификатор 'ref' фактически ничего не делает, поскольку вы не присваиваете ничего обратно' b'. Копирование ссылки всегда выполняется, и как переменная, так и параметр в конечном итоге указывают на тот же объект. – Alejandro

ответ

2

ли a будет ссылка на b или a собирается скопировать значение, которое ref b указывает на?

Это зависит:

, если Boo является ссылочным типом, например, как показано ниже, a будет указывать на тот же экземпляр после вызова

public class Boo 
{ 
    public int Number { get; set; } 
} 

If Boo имеет тип значения, такие, как ниже, a будет по очереди копией того, что указывало на ref b.

public struct Boo 
{ 
    public int Number { get; set; } 
} 
0

Пожалуйста, обратитесь к следующему примеру:

public class Foo 
    { 
     public string Name { get; set; } 
    } 

    public class Bar 
    { 
     public Foo MyFoo { get; set; } 

     public Bar(Foo paramFoo) 
     { 
      this.MyFoo = paramFoo; 
     } 
    } 

И эта последовательность:

 Foo f = new Foo(); 
     f.Name = "First Foo"; 

     System.Diagnostics.Debug.WriteLine(f.Name); 

     Bar b = new Bar(f); 

     System.Diagnostics.Debug.WriteLine(b.MyFoo.Name); 

     b.MyFoo.Name = "Renaming Bar Name"; 

     System.Diagnostics.Debug.WriteLine(f.Name); 
     System.Diagnostics.Debug.WriteLine(b.MyFoo.Name); 

Выход будет:

First Foo 
First Foo 
Renaming Bar Name 
Renaming Bar Name 

В этом случае, мы» переходя f ссылка t o Bar ctor, поэтому f и MyFoo оба указывают на тот же адрес памяти, , но это разные переменные. Это означает, что, если мы делаем следующее

 b.MyFoo = new Foo(); 
     b.MyFoo.Name = "Yet another foo"; 

     System.Diagnostics.Debug.WriteLine(f.Name); 
     System.Diagnostics.Debug.WriteLine(b.MyFoo.Name); 

Выход будет

Renaming Bar Name 
Yet another foo 

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

+0

Downvoters, пожалуйста, оправдайте! –

+0

В этом случае я не спустил вниз, но я подозреваю, что нисходящее - это то, что с вашим ответом есть пара вопросов.(a) «известные типы значений» вводят в заблуждение - вы можете создать свой собственный тип значения, и он будет передан по значению. (b) использование 'ref' не приводит к тому, что типы значений ведут себя как ссылочные типы; он просто передает значение аргумента по ссылке. Передача ссылочного типа по ссылке отличается от передачи ссылочного типа по значению. –

+0

@MichaelPetito Если вы перейдете к ссылке, которую я предоставил, вы увидите, что перечисления и структуры являются первыми элементами, которые разрешают часть «вы можете создать свой собственный тип значения». Использование 'ref' с типом значения передаст его как ссылочный тип. Использование 'ref' с ссылочным типом не имеет дополнительного значения. –

0

Существует, конечно, различие в прохождении стандартных ссылок и с использованием ключевого слова ref.

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

class Class6 
{ 
    static void Main(string[] args) 
    { 
     Boo b = new Boo { BooMember = 5 }; 
     Console.WriteLine(b.BooMember); 

     Foo f = new Foo(b); 
     // b is unaffected by the method code which is making new object 
     Console.WriteLine(b.BooMember); 

     Foo g = new Foo(ref b); 
     // b started pointing to new memory location (changed in the method code) 
     Console.WriteLine(b.BooMember); 
    } 
} 

public class Foo 
{ 
    Boo a; 
    public Foo(Boo b) 
    { 
     a = b; 

     // b is just a reference, and actually is a copy of reference passed, 
     // so making it point to new object, dosn't affect actual object , check in calling code 
     b = new Boo(); 
    } 

    public Foo(ref Boo b) 
    { 
     a = b; 

     // b is just a reference, but actual reference itself is copied, 
     // so making it point to new object would make the calling code object reference to point 
     // to new object. check in the calling code. 
     b = new Boo(); 
    } 
} 

public class Boo 
{ 
    public int BooMember { get; set; } 
} 
Смежные вопросы