2014-06-06 99 views
0

我在閱讀關於C#中的結構和類,並且我的理解結構是值類型,類是引用類型。但是我對當類對象作爲參數傳遞給方法時的行爲有些困惑。引用類型與值類型

假設我有以下代碼:

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     var program = new Program(); 
     var person = new Person 
     { 
      Firstname = "Bob", 
     }; 

     Console.WriteLine(person.Firstname); 
     program.ChangeName(person); 
     Console.WriteLine(person.Firstname); 
     program.Kill(person); 
     Console.WriteLine(person.Firstname); 
     Console.Read(); 
    } 

    public void ChangeName(Person p) 
    { 
     p.Firstname = "Alice"; 
    } 

    public void Kill(Person p) 
    { 
     p = null; 
    } 
} 

當我通過我的Person類的實例來Program.ChangeName()和改變person.FirstnameAlice值,更改將反映原來的人對象上的實例我的Program.Main()這是我所期望的,p參數是對person的參考。但是,當我嘗試將p設置爲null時,看起來沒有變化。爲什麼是這樣?

+2

參數的人員P是一個對象的引用。當你將它清空 - 你只是將參考而不是對象歸零。 – tim

+2

因爲'p'是被調用方法的局部變量。你所做的只是將局部變量的引用改爲null,而不是傳入的person對象。 – itsme86

+1

C#中的所有參數都通過值*傳遞,除非它們特別標記爲'ref'或'out'。在結構體的情況下,結構體的全部內容都是傳遞的值。如果修改它,則更改不會影響原始內容,因爲您修改了副本。在類的情況下,只有對象的引用被傳遞,但*引用*是通過值傳遞的。重新分配參考副本不會影響原稿。但是,您可以操作對象的內容,因爲原始引用和複製的引用指向同一對象。 –

回答

3

當你「通過引用傳遞」時,你確實傳遞了引用的副本,因此將該引用設置爲指向另一個對象(或null)不會影響原始引用。但是,如果通過取消引用指針副本來更改對象的屬性,則調用者將看到這些更改。

如果你想真正通過引用傳遞,使你的殺法正常工作,您可以添加ref關鍵字:

public void Kill(ref Person p) 
{ 
    p = null; 
} 
3

您正在將參考副本設置爲null,但不影響原始值。

它類似於(在C++)

Person * myPtr = new Person(); 
NullFunc(myPtr); 

public NullFunc(Person * ptr) 
{ 
    ptr = null; 
} 

參考被有效地由值來傳遞,則不能改變它。但是,您可以更改它指向的對象的屬性:

ptr->Name = "Bob"; 

明顯影響原始對象。