分配给空引用类型

Assign to null reference type

请理解我看到并关注了这个问题,但不确定如何彻底解决它。我正在尝试 运行 我的 Add 方法,迭代直到找到我的密钥或当前节点为空,然后 return reference 到节点,如果为空则赋值。我的代码(见添加方法中的注释):

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 的全部意义在于尝试 return 对已找到的任何节点的引用,即使它为 null .在本例中,这是添加的第一个项目,因此 TraverseDown 方法应该 returning 对我的 _baseNode 的引用,默认为 null。然而,这只是将局部变量设置为 newNode,而 _baseNode 保持为空。

我确定对此有一个简单的答案,但我已经研究了一点但一无所获。非常感谢任何帮助!

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

return currentNode;

您 return currentNode,不是参考。由于值为 null,您总是 return null(因为您的 if (currentNode == null... 语句)。

当你分配...

nodeToUpdate = newNode;

...您只需分配一个 null 引用。

真正要给TraverseDown中的_baseNode赋值时,需要在方法内设置currentNode

currentNode = //Value

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