Как я могу использовать ref для изменения этой переменной класса в C #? - PullRequest
0 голосов
/ 18 октября 2011

Я пытаюсь использовать ключевое слово ref в C #, чтобы изменить переменную класса, переданную функции-делегату. Я хочу, чтобы функция делегата могла изменять значения, хранящиеся в контейнере, для родителя и двух его потомков. В настоящее время происходит то, что функция делегата может изменять родительский элемент (поскольку я передаю ссылку непосредственно в контейнер [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);
        }
    }
    

Ответы [ 2 ]

1 голос
/ 18 октября 2011

Что вам нужно, так это указатели, а C # не предоставляет их - к счастью.

Вы можете просто присвоить значения обратно переменной класса:

operation(ref container[parentIndex], ref leftChild, ref rightChild);
container[leftChildIndex] = leftChild;
container[rightChildIndex] = rightChild;
1 голос
/ 18 октября 2011

Проблема в том, где вы их определяете:

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));
        }
    }
}
...