2016-12-29 68 views
0

請理解,我看到並遵循該問題,但我不確定如何徹底解決此問題。我嘗試運行我的增加方法,迭代直到找到我的密鑰或當前節點爲空,然後將引用返回給節點並分配它是否爲空。我的代碼(見add方法評論):分配給空引用類型

public class MyClass<TKey, TValue> 
{ 
    private Node _baseNode; 

    public void Add(TKey key, TValue value) 
    { 
     var newNode = new Node(key, value); 

     //this returns null, as is expected. 
     var nodeToUpdate = TraverseDown(ref _baseNode, newNode.Key); 

     if (nodeToUpdate != null) 
      throw new ArgumentException("Cannot add a duplicate key."); 

     //here, I try to assign a value to _baseNode because I'd like 
     //nodeToUpdate to hold the reference to _baseNode 
     nodeToUpdate = newNode; 
    } 

    private Node TraverseDown(ref Node currentNode, int keyToFind) 
    { 
     if (currentNode == null || currentNode?.Key == keyToFind 
      || currentNode?.Edge == null) 
     { 
      //on first add, this is what is getting hit - as expected 
      return currentNode; 
     } 
     else 
     { 
      //these are being explicitly set to local variables because i was 
      //experimenting with passing them byRef, and that can't be done on 
      //properties 
      var leftNode = currentNode.Edge.LeftNode; 
      var rightNode = currentNode.Edge.RightNode; 
      return keyToFind < currentNode.Key 
          ? TraverseDown(ref leftNode, keyToFind) 
          : TraverseDown(ref rightNode, keyToFind); 
     } 
    } 
} 

具有TraverseDown方法接受一個節點BYREF是試圖返回參照已發現的任何節點,即使它的整個點空值。在這種情況下,這是第一個被添加的項目,所以TraverseDown方法應該將引用返回給我的_baseNode,null爲默認值。然而,這只是將局部變量設置爲newNode,並且_baseNode保持爲空。

我確信這個問題有一個簡單的答案,但我一直在研究一點,沒有發現任何東西。請任何幫助,非常感謝!

回答

1

您的TraverseDown方法中沒有行,您實際上指定了ref currentNode。相反,你會返回它的價值。當您傳遞參數ref時,並不意味着該值將在整個方法範圍內被視爲參考。 參數本身將被視爲參考,而不是其價值。所以,當你寫...

return currentNode; 

您返回價值currentNode,而不是參考。由於價值是null,您總是會返回null(因爲您的if (currentNode == null...聲明)。

當您指定...

nodeToUpdate = newNode; 

...你只需指定一個null參考。

當你真正想在TraverseDown值分配給_baseNode,你需要在方法中設置currentNode

currentNode = //Value 

注意in C# 7.0 there will be ref returns,這表現在你在你的方法治療currentNode的方式。

+0

謝謝你這麼快回復,這非常有道理。請閱讀C#7.0鏈接,瞭解一些有趣的內容。 我想這是按預期運行,但是如何編寫代碼變得複雜。我需要'TraverseDown'方法來執行搜索,而不是分配。想想這意味着我只需明確地在add方法中設置頂層節點,並從其上面可能返回父節點,而不是我想要直接處理的節點。除非你有其他想法?再次感謝! – Switch386

+0

@Switch386,如果您不讓該方法進行分配,作爲參考傳遞沒有多大意義。如果你不想這樣做,那麼返回你想要添加新子節點的節點(即新的父節點)確實會更有意義。 – Sefe

相關問題