2016-09-16 28 views
1

我從未意識到過這樣的問題。如果我傳遞了一個具有特定類型但尚未實例化的變量,那麼它不應該被視爲一個指針嗎?在這個例子中,爲什麼如果方法GetEmployee創建一個新的實例,我回到了單擊事件的範圍時,我得到了空值。傳遞一個類的變量作爲之前定義爲null的參數

我知道爲了使它工作,我可以將參數定義爲ref或out,但Employee是一個最初被定義爲null的類,但是當我做新的時候,我會在內存中分配一個空間,不要鏈接到變量?爲什麼我以後失去價值?

如果我傳遞一個對象,那麼當我回到click事件的範圍時,內部方法中所有修改過的屬性將保持不變的情況將完全不同。

這將無法正常工作

protected void btnTest_Click(object sender, System.EventArgs e) 
    { 
     Employee employee = null; 
     bool created = GetEmployee(employee); 
    } 

這將工作

protected void btnTest_Click(object sender, System.EventArgs e) 
    { 
     Employee employee = new Employee(); 
     bool created = GetEmployee(employee); 
    } 

其餘

private bool GetEmployee(Employee employee) 
    { 
     if (employee == null) 
     { 
      employee = new Employee(); 

     } 
     employee.ID = 1; 
     employee.Name = "John"; 
     return true; 
    } 

    public class Employee 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
    } 

UPDATE:

的COM把事情稍微折騰一下。這也將失敗,因爲該對象從未被設置爲不同的東西,以空

protected void btnTest_Click(object sender, System.EventArgs e) 
    { 
     int id = 1; 
     Employee employee = this.LoadFromDatabase(id); 
     bool created = GetEmployee(employee); 
    } 

    private Employee LoadFromDatabase(id) 
    { 
     //In the inner service method if it is not found it will return null 
     return Service.Instance.LoadFromDatabase(id); 
    } 

    private bool GetEmployee(Employee employee) 
    { 
     if (employee == null) 
     { 
      employee = new Employee(); 

     } 
     employee.ID = 1; 
     employee.Name = "John"; 
     return true; 
    } 

回答

0

Employee是引用類型,這是什麼意思是,它實際上員工數據的地址。

GetEmployee中的employee參數只是該地址的副本。由於您知道地址,因此您可以更改地址上的信息,但因爲它只是一個副本,所以您對地址本身做出的任何更改(例如employee = new Employee();)都不會影響您通過的地址。

當您做employee = new Employee();你已經覆蓋了複製的地址,新的地址指向一個完全不同的員工在內存中。這就是爲什麼你沒有看到你通過的員工有任何變化。

2

雖然員工的成員可以由調用者修改,但員工本身的引用不能。在C#中傳入引用類型參數時,您可以修改該對象的成員並查看調用者中的更改。但是,引用本身是通過值傳遞的,並且分配給參數不會執行任何操作。做你想做什麼,只是返回的員工,而不是錯誤地試圖修改參考:

private Employee GetEmployee(Employee employee) 
{ 
    if (employee == null) 
    { 
     return new Employee() 
     { 
      ID = 1, 
      Name = "John", 
     }; 
    } 

    employee.ID = 1; 
    employee.Name = "John"; 
    return employee; 
} 
+0

https://blogs.msdn.microsoft.com/csharpfaq/2004/03/11/how-are-parameters-passed-in-c-are-they-by-reference-by-value/ – Jakotheshadows

+0

對,在這種情況下,值是引用,你不能改變引用,因此分配某些參數在調用者中沒有任何作用。 – Jakotheshadows

+0

我不確定它是如何錯誤地傳遞參考的。 REFERENCE是按值傳遞的。我會編輯我的答案,以明確表示。 – Jakotheshadows

0

當你傳遞一個引用類型整個方法,一個方法參數將是一個新的參考同一對象,除非您使用ref關鍵字

public class A {} 

public class B 
{ 
    public void DoStuff(A a) // <--- "a" is a new reference of type A 
    { 
     a = new A(); 
    } 
} 

所以...

調用DoStuff用下面的代碼:

A a = null; 
DoStuff(a); 

...會給A類型的空引用DoStuff。也就是說,您不會在方法調用期間使用給定的引用,但參數因此不會將源引用更新爲指向新對象。

否則,你將需要使用ref關鍵字無論是在方法簽名,當你的地方把它叫做:

public class B 
{ 
    public void DoStuff(ref A a) // <--- "a" is a new reference of type A 
    { 
     // Now this will affect the reference that was passed 
     // when this method is being called! 
     a = new A(); 
    } 
} 

B b = new B(); 
A a = new A(); 
b.DoStuff(ref a);