2012-12-06 44 views
3
public class TreeNode 
{ 
    public TreeNode Left; 
    public TreeNode Right; 
    public int Data { get; set; } 

    public TreeNode(int data) 
    { 
     Left = null; 
     Right = null; 
     Data = data; 
    } 
} 



    public class BinarySearchTree 
{ 
    private TreeNode _root; 

    public BinarySearchTree() 
    { 
     _root = null; 
    } 

    public void Insert(int data) 
    { 
     TreeNode tempNode = null; 

     Insert(_root, tempNode); 
    } 

    private void Insert(TreeNode treeNode, TreeNode newNode) 
    { 
     newNode = new TreeNode(3); 
     treeNode = new TreeNode(4); 
    } 

在這個例子中,公共無效Insert(int data)方法基本上只是調用私有方法,我把一個破發點在public void Insert(int data)方法結束。C#引用類型的問題

和通知_root仍爲空,而tempNode爲4.我不明白爲什麼?任何人都可以解釋嗎?

+0

代碼是否編譯? Insert(int)中定義newNode在哪裏? – manojlds

+0

您正在通過價值參考。如果你做了treeNode.DoWork()它會作用於被引用的對象,但是如果你重新分配了treeNode,你將重新分配引用本身(這是通過值傳遞的)。 – Michael

+1

框架設計指南(Krzysztof Cwalina和Brad Abrams撰寫的一本書)建議避免ref和out參數。使用'out'和'ref'幾乎不存在很好的理由。 – 2012-12-06 17:48:18

回答

3

按引用傳遞使用類ref關鍵字:

private void Insert(ref TreeNode treeNode, ref TreeNode newNode) 
{ 
    newNode = new TreeNode(3); 
    treeNode = new TreeNode(4); 
} 

在你原來的方法只副本引用上課都通過了,它們不是通過引用傳遞。所以如果你在做new你只是替換類引用的本地副本,但調用方法仍然保留原始參考值。結果,新創建的值不會返回給調用者。

更改Insert(data)方法(不ref關鍵字編譯器會給你一個錯誤):

public void Insert(int data) 
{ 
    TreeNode tempNode = null; 
    Insert(ref _root, ref tempNode); 
} 

這實際上是一個編譯器的要求,只是爲了確保來電者知道,傳遞的對象可以被替代方法調用後的其他對象。

您可能還想閱讀關於out的關鍵字。雖然ref參數應在調用之前初始化,但out參數預計將在方法內初始化。

0

您正在傳遞引用類型,但它實際上傳遞了引用的副本。更新該副本不會更新原件。

要解決此問題,請使方法返回新值。或者你可以修改你的函數來使用參數。

private void Insert(out TreeNode treeNode, out TreeNode newNode) 
{ 
    newNode = new TreeNode(3); 
    treeNode = new TreeNode(4); 
} 
+0

在這裏使用'ref'應該沒有問題,因爲只要他在函數和函數調用中使用'ref'關鍵字,他就會創建一個新對象。 – 2012-12-06 17:55:31

+0

+1給所有參考/建議。不幸的是,該方法的原始名稱使得很難理解預期的行爲是什麼... –

0

看一看的out,並且ref修飾符參數。例如,你可以

private void Insert(ref TreeNode treeNode, TreeNode newNode)