C # и сохранение ссылки на параметр метода - PullRequest
0 голосов
/ 28 октября 2009

Для небольшого количества справочной информации у меня есть приложение, которое работает в цикле, и при любой отметке оно вызывает метод 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 работает нормально и всегда получает правильное значение. Проблема в том, что вы не можете сохранить ссылку на другую переменную в классе, поэтому, когда я делаю новый C (ссылка одна); и конструктор для C устанавливает переменную класса в единицу, позже после того, как одна обновляется в A, это похоже на то, что C больше не знает, что он все еще должен указывать на единицу (которая теперь обновлена) и просто пуст (как это было изначально был внутри конструктора). Любая идея о том, как добиться того, что я ищу, без использования указателей C # и небезопасного кода? Спасибо, надеюсь, это имеет смысл:)

Edit: Очевидно, что люди не могут отвечать на вопросы с запутанным псевдокодом, который совершенно не связан с реальным вопросом, поэтому изменение распространяется на:

Редактировать 2: класс C

...
ArrayList local;
...
C(ref ArrayList one){
    local = one;
}

Tick(){
   LastValue = local[0] + 5; //not actual formula, just shows trying to use a referenced variable 
}

Ответы [ 3 ]

2 голосов
/ 28 октября 2009

Поскольку one - это ArrayList, вы можете только передать его в качестве ссылки. Теперь вы, очевидно, передаете его как ссылку на конструктор. Вам может не понадобиться ref.

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

Edit:

После просмотра вашего класса C вам не понадобится ref. c поделится экземпляром ArrayList, который A вызывает one.

Это, кажется, сводится к общей проблеме ссылочного типа / значения типа в .NET. Подведем итог:

  • экземпляры объектов не имеют имени и не могут (физически) вообще передаваться в качестве параметра.
  • вы всегда обращаетесь к экземпляру через ссылку. В вашем коде one (2x), two, local - все ссылки на экземпляры Arraylist.
  • сами ссылки ведут себя как тип значений, т. Е. Присвоение означает копирование.

Чтобы узнать больше о ссылочных типах / типах значений, поищите «копировать семантику» и избегайте публикаций, которые начинаются с «значений типов существуют в стеке».

0 голосов
/ 28 октября 2009

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

0 голосов
/ 28 октября 2009

вы не можете сохранить ссылку на другую переменную в классе

Вы можете, люди делают это постоянно. Просто назначьте его (частному) полю.

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

PPS: перечитывая ваш (отредактированный) код и все еще пытаясь выяснить, в чем проблема, кажется, нет ничего, что мешало бы C в вашем коде сохранять элемент со ссылкой на A и вызов a.Add также будет отражать переменную-член в c. Действительно, здесь ref не нужно.

...