分配给空引用类型

时间:2016-12-29 06:33:07

标签: c# .net c#-4.0 null pass-by-reference

请理解我看到并关注此问题,但不确定如何彻底解决问题。我正在尝试运行添加方法,迭代直到找到我的密钥或当前节点为空,然后将引用返回到节点并分配它是否为null 。我的代码(请参阅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方法接受Node byRef 的全部意义是尝试将引用返回到找到的任何节点,即使它是null。在这种情况下,这是第一个添加的项,因此TraverseDown方法应该返回对我的_baseNode的引用,null为默认值。但是,只需将局部变量设置为newNode,_baseNode保持为空。

我确信这方面有一个简单的答案,但我一直在研究,没有发现任何东西。拜托,非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

TraverseDown方法中没有您实际分配ref currentNode的行。相反,你返回它的价值。传递ref参数时,并不意味着该值将在整个方法范围内被视为引用。 参数本身将被视为参考,而不是其值。所以当你写...

return currentNode;

您返回currentNode,而不是引用。由于值为null,因此您始终返回null(因为您的if (currentNode == null...语句)。

分配时......

nodeToUpdate = newNode;

...您只需指定一个null参考。

如果您确实要在_baseNode中为TraverseDown分配值,则需要在方法中设置currentNode

currentNode = //Value

请注意in C# 7.0 there will be ref returns,其行为与您在方法中处理currentNode的方式相同。