Подтвердить что ты не робот

Как сохранить переменную ref для последующего использования?

Итак, это работает.

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", а повторная привязка к ней больше не изменяет входную переменную. Есть ли способ обойти это?

4b9b3361

Ответ 1

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

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 не очень хорош для читаемости. Если вы можете объяснить большую картину того, чего вы пытаетесь достичь, мы сможем предложить лучший общий подход.

Ответ 2

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

И действительно, то, что вы пытаетесь там, обречено с самого начала.

Ответ 3

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

Нет, нет: это невозможно.

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

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

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

Ответ 4

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

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