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