【问题标题】:How can I use ref to modify this class variable in C#?如何使用 ref 在 C# 中修改此类变量?
【发布时间】:2011-12-10 04:45:07
【问题描述】:

我正在尝试使用 C# 中的 ref 关键字来修改传递给委托函数的类变量。我希望委托函数能够修改存储在容器中的父级及其两个子级的值。现在发生的情况是委托函数可以修改父函数(因为我直接将引用传递给容器 [parent])但不能修改子函数,因为我必须先处理它们并因此传递对 leftChild 和 rightChild 的引用。

  • 是否可以让leftChild 成为对容器[leftChildIndex] 的引用,以便委托函数可以修改存储在容器中的值? (右孩子也一样)

    private void traversePostOrder(Modify operation, int parentIndex) {
        if (parentIndex < size) {
            int leftChildIndex = getLeftChildIndex(parentIndex);
            int rightChildIndex = getRightChildIndex(parentIndex);
            T parent = container[parentIndex];
            T leftChild = default(T);
            T rightChild = default(T);
    
            Library.Diagnostics.Message.logMessage("P: " + parent, 2);
    
            if (leftChildIndex < container.Length) {
                traversePostOrder(operation, leftChildIndex);
                leftChild = container[leftChildIndex];
            }
    
            if (rightChildIndex < container.Length) {
                traversePostOrder(operation, rightChildIndex);
                rightChild = container[rightChildIndex];
            }
    
            operation(ref container[parentIndex], ref leftChild, ref rightChild);
        }
    }
    

【问题讨论】:

    标签: c# delegates ref


    【解决方案1】:

    问题在于你在哪里定义它们:

    T leftChild = default(T);
    T rightChild = default(T);
    

    您传递对这些对象的引用,它们在方法结束后立即被销毁,因为它们是局部变量。
    尝试直接发送对象。

    private void traversePostOrder(Modify operation, int parentIndex) {
        if (parentIndex < size) {
            int leftChildIndex = getLeftChildIndex(parentIndex);
            int rightChildIndex = getRightChildIndex(parentIndex);
            T parent = container[parentIndex];
            bool leftChildModified = false;
            bool rightChildModified = false;
    
            Library.Diagnostics.Message.logMessage("P: " + parent, 2);
    
            if (leftChildIndex < container.Length) {
                traversePostOrder(operation, leftChildIndex);
                leftChildModified = true;
            }
    
            if (rightChildIndex < container.Length) {
                traversePostOrder(operation, rightChildIndex);
                rightChildModified = true;
            }
    
            if(leftChildModified && rightChildModified)
            {
                operation(ref container[parentIndex], ref container[leftChildIndex], ref container[rightChildIndex]);
            }
            else if(leftChildModified)
            {
                operation(ref container[parentIndex], ref container[leftChildIndex], ref Default(T));
            }
            else if(rightChildModified)
            {
                operation(ref container[parentIndex], ref Default(T), ref container[rightChildIndex]);
            }
            else
            {
                operation(ref container[parentIndex], ref default(T), ref default(T));
            }
        }
    }
    

    【讨论】:

    • 不幸的是,当我尝试ref leftChildModified ? container[leftChildIndex] : default(T) 时发生错误,右孩子也是如此。它说 ref 必须是一个可赋值的变量。
    • 不确定这个的三元组;),请参阅我编辑的答案。
    • 哈哈,这会引发更多(语法)错误。不过我明白你在说什么。谢谢您的帮助!是否可以将三元运算符分配给变量,然后在那里使用该变量?还是只会重现我原来的问题?
    • 您可以使用 4 种不同的可能性并使用正确的参数调用操作。我将再次编辑我的答案。
    【解决方案2】:

    您正在寻找的是指针,而 C# 没有公开它们 - 幸运的是。

    您可以简单地将值分配回类变量:

    operation(ref container[parentIndex], ref leftChild, ref rightChild);
    container[leftChildIndex] = leftChild;
    container[rightChildIndex] = rightChild;
    

    【讨论】:

      猜你喜欢
      • 2013-04-15
      • 2020-11-29
      • 2013-02-22
      • 2022-01-09
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      相关资源
      最近更新 更多