Как сохранить переменную ref для дальнейшего использования? - PullRequest
15 голосов
/ 31 августа 2011

Так что это работает ..

public MyClass(ref Apple apple)
{
    apple = new Apple("Macintosh"); // Works fine
}

Но возможно ли сделать что-то подобное?

private Apple myApple;

public MyClass(ref Apple apple)
{
    myApple = apple;
}

public void ModifyApple()
{
    myApple = new Apple("Macintosh"); // does not change the input variable like the first example did
}

Когда переменная ref копируется в переменную-член myApple, она, похоже, теряет свое «ref-ness», и переназначение ее больше не меняет входную переменную. Есть ли способ обойти это?

Ответы [ 4 ]

9 голосов
/ 31 августа 2011

ref -ness - это свойство параметров функций и аргументов, которые вы передаете функциям.Это вообще не свойство переменных (или даже полей).

Так что то, что вы пытаетесь там, обречено с самого начала.

6 голосов
/ 31 августа 2011

Не совсем, нет.К тому времени, когда ваш код будет вызван в следующий раз, исходная переменная, используемая в качестве аргумента метода, может уже не существовать:

void Foo()
{
    MyClass x = Bar();
    x.ModifyApple();
}

MyClass Bar()
{
    Apple apple = new Apple();
    return new MyClass(ref apple);
}

Здесь apple - это локальная переменная вкадр стека, который будет вытеснен к тому времени, когда мы вызовем ModifyApple.

Вы уверены, что вам нужно изменить переменную исходного вызывающего , а не просто изменить сам объект?

Один из способов сортировки фальшивок: использовать для начала тип обертки:

public class MutableWrapper<T>
{
    public T Value { get; set; }
}

Затем передать MutableWrapper<Apple> и сохранить его в своем классе.,Затем в ModifyApple вы можете написать:

wrapper.Value = new Apple();

Это не изменит переменную вызывающего абонента , но в следующий раз, когда вызывающий объект смотрит на свойство Value, он увидитваше новое яблоко.

Если честно, такого рода вещи имеют тенденцию создавать трудно поддерживаемый код, и даже ref не очень хорош для читабельности.Если вы сможете объяснить более полную картину того, чего вы пытаетесь достичь, мы можем предложить лучший общий подход.

3 голосов
/ 31 августа 2011

Нет, нет. myApple - это поле, которое содержит ссылку на Apple; параметр apple, однако, на самом деле является ссылкой на ссылку на Apple. Когда вы присваиваете apple myApple, вы разыменовываете значение параметра . Кроме того, они являются отдельными и отличными.

Так нет: это невозможно.

Что бы было бы возможно , это иметь что-то вроде:

public class AppleWrapper {
    public Apple Value {get;set;}
}

Теперь; если вы храните AppleWrapper, любое количество абонентов может получить доступ к и изменить .Value

0 голосов
/ 31 августа 2011

Почему бы просто не ModifyApple вернуть измененный экземпляр Apple?

public Apple ModifyApple()
{
    myApple = new Apple("Macintosh"); // does not change the input variable like the first example did
    return myApple;
}
...