Collin
@Collin

Как использовать объект из другого метода в консольном приложении C#?

Здравствуйте. Помогите, пожалуйста, разобраться. Не пойму, как использовать экземпляр объекта в другом методе:

public void Data()
{
   // Смотрю список портов, выбираю нужный и далее...
   SerialPort port1 = new SerialPort(portName);
   port1.BaudRate = 9600;
   poert1.StopBits = StopBits.One;

   port1.Open();

   port1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

   // Выполняю какие-то еще действия
}

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
   Console.WriteLine("Получил ответ");

   //тут мне нужно поработать с моим портом port1
   int buffSz = port1.BytesToRead; //И ожидаемо port1 не существует в текущем контексте
}


Как правильно работать с экземпляром объекта SerialPort и вообще с любым другим экземпляром объекта из другого метода?
В wpf я как-то и не сталкивался с такой проблемой. Сначала подумал про делегаты, но, это по-моему не совсем то, что нужно в данном случае.
  • Вопрос задан
  • 536 просмотров
Решения вопроса 1
petermzg
@petermzg
Самый лучший программист
Никак.
Метод это изолированное пространство и доступа к локальным переменным этого пространства нет.
Но в вашем случае инстанс обьекта SerialPort передает ссылку на свой экземляр в подсоединяемый делегат, через параметр sender и в нем вы можете сделать так:
var port = (SerialPort)sender;
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
lexxpavlov
@lexxpavlov
Программист, преподаватель
Обратиться к объекту можно обратиться только по ссылке на него. Если есть ссылка - можно использовать.
Ссылка на объект port1 сохранена в локальной переменной метода Data. После окончания вызова этого метода, все локальные переменные исчезают. Чтобы обратиться на этот объект из другого метода, есть несколько способов:
1) сохранить ссылку в поле класса, а не в локальную переменную. Доступ к полям есть во всех методах класса (кроме статических).
2) если второй метод вызывается из первого, то во второй метод можно передать ссылку аргументом. У вас второй метод не вызывается из метода Data, в этом случае, так не получится использовать.
3) сам объект может передать ссылку на себя другим объектам, тогда те смогут его использовать (это как раз у вас и происходит, как и сказал Петр)

Обратите внимание, что если бы вы не сделали добавление обработчика события, то после завершения вызова метода Data, не оставалось бы ни одной ссылки на этот объект, и сборщик мусора (GarbageCollector, GC) отметил бы его мусором и удалил бы его (раньше или позже). А раз вы сделали обработчик события, то этот объект не является мусором (он используется другим объектом). Мусором он станет, когда вы удалите обработчик события.

Каким способом передавать ссылку лучше всего? В зависимости от контекста (т.е. от способа использования этого объекта):
1) если вы создали временный объект, который вы использовали и больше не нужен, то передавайте ссылку на него аргументами при вызове методов, его используемых. Когда объект больше не нужен, GC быстро и безболезненно удалит его.
2) если вы создали постоянный объект, который должен работать какое-то время после окончания метода, в котором объект создан, то нужно положить ссылку на него в поле класса (или в список, или ещё куда-нибудь). Пока есть ссылка, остаётся объект. Когда он уже не нужен, то нужно удалить ссылку на него (присвоить в поле null или новую ссылку, удалить из списка и пр.). Не забывайте обнулять ссылки на не нужные объекты!
3) Можно использовать косвенные ссылки (например, обработчики события), но это обычно неудобно - не ясно, когда исчезнут ссылки на объект, а в некоторых случаях, удалить обработчик уже не получится (опять же, это сложно сделать без ссылки). Подобные вещи - места для трудноуловимых багов. Поэтому, лучше использовать способы 1 или 2.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы