C # и сохранение ссылки на параметр метода
-
06-07-2019 - |
Вопрос
Для получения небольшой справочной информации, у меня есть приложение, которое выполняется в цикле, и с течением времени оно вызывает метод Tick .Есть куча классов, которые расширяют базовый класс, и у всех есть свои собственные методы tick, и они добавляются в цепочку зависимостей, так что, скажем, когда вызывается класс A и в его цепочке есть экземпляры B и C, вызывается B.Tick, за которым следует C.Tick и, наконец, A.Tick.
Итак, в псевдокоде мой класс выглядит примерно так:
public class A : Super
Super b;
Super c;
ArrayList one;
ArrayList two;
tick(){
one.Add(b.LastValue);
two.Add(c.LastValue);
... do something with one and two ...
}
A(){
b = new B(some other array list);
c = new C(ref one);
}
B работает нормально и всегда получает правильное значение.Проблема в том, что, я думаю, вы не можете сохранить ссылку на другую переменную в классе, поэтому, когда я делаю new C (ссылка one);и конструктор для C устанавливает переменную класса в единицу, позже, после обновления единицы в A, это похоже на то, что C больше не знает, что она все еще должна указывать на единицу (которая теперь обновлена) и просто пуста (как это изначально было внутри конструктора).Есть какие-нибудь идеи о том, как достичь того, что я хочу сделать, без необходимости использовать указатели C # и небезопасный код?Спасибо, надеюсь, это имеет смысл :)
Редактировать:По-видимому, люди не могут отвечать на вопросы с помощью запутанного псевдокода, который совершенно не связан с реальным вопросом, поэтому измененный распространяется на :
Правка 2:Класс С
...
ArrayList local;
...
C(ref ArrayList one){
local = one;
}
Tick(){
LastValue = local[0] + 5; //not actual formula, just shows trying to use a referenced variable
}
Решение
С тех пор как one
является ArrayList, вы можете Только передайте его в качестве ссылки.Теперь вы, по-видимому, передаете его как ссылку на ссылку на конструктор.Возможно, вам это не понадобится ref
.
Но, пожалуйста, покажите более полное представление о том, чего вы пытаетесь достичь.
Редактировать:
После просмотра вашего класса C нет необходимости в ref
. c
будет совместно использовать экземпляр ArrayList, который вызывает A one
.
Похоже, это сводится к общей проблеме referencetype / valuetype в .NET.Подводя итог:
- экземпляры объектов не имеют имени и вообще не могут (физически) быть переданы в качестве параметра.
- вы всегда получаете доступ к экземпляру через ссылку.В вашем коде,
one
(2 раза) ,two
,local
все это ссылки на экземпляры Arraylist. - сами ссылки ведут себя как valuetypes, т. е. присвоение означает копирование.
Чтобы узнать больше о ссылочных типах / типах значений, выполните поиск "копировать семантику" и избегайте записей, начинающихся с "типы значений существуют в стеке".
Другие советы
Нет ничего, что могло бы помешать тебе сделать это.Хотя, хорошая это идея или нет, это другой вопрос.В общем, я бы рекомендовал стараться избегать изменения состояния между вызовами метода, если вы можете этого избежать.Конечно, ключевое выражение там - "если вы можете избежать этого".:-)
вы не можете сохранить ссылку на другую переменную в классе
Вы можете, люди делают это постоянно.Просто назначьте его (закрытому) полю.
поэтому, когда я делаю новый C (ссылка одна);[snip /] позже, после обновления одного из них в A, это похоже на то, что C больше не знает, что он все еще должен указывать на один
На самом деле, он знает это, но вы должны назначить one
в поле участника.Присвоение объектам - это не что иное, как установка ссылки на объект.Изменяя объект, изменяйте их везде, где вы ему назначили:
class A
{
public string Hello { get; set; }
}
class C
{
private A myA;
public C(A a) { myA = a; }
public A GetMyA() { return myA; }
}
// somewhere else:
A someA = new A();
someA.Hello = "Hello World";
C someC = new C(someA);
someA.Hello = "Other World";
Console.WriteLine(someC.GetMyA().Hello);
// this will print "Other World" and not "Hello World" as you suggest
PS:поскольку вы публиковали псевдокод, я надеюсь, вы не возражаете, что я немного его упростил.Если я неправильно понял ваш вопрос, то, пожалуйста, проигнорируйте (и, возможно, уточните, если возможно).
ППС:перечитывая ваш (отредактированный) код и все еще пытаясь выяснить, в чем проблема, кажется, ничто не мешает C
в вашем коде от сохранения участника со ссылкой на A
и зовущий a.Add
очевидно, будет отражать переменную-член в c
также.Действительно, нет необходимости в ref
вот.