ByRef не проходит через vb.net

#vb.net #object

#vb.net #объект

Вопрос:

Один вызывает форму 2 как диалоговое окно и передает ref «указатель» на базовый класс (абстрактный). // Форма 1 вызывает вторую форму. И передает объект ref

 Dim CreateForm As New frmCreate(Robot)
  

// Вторые формы перегружены новыми

 Public Sub New(ByRef Robot As cRobot)
    InitializeComponent()
    thisRobot = Robot
End Sub

Select Case (cbType.SelectedIndex)
        Case 0
            lblOther.Text = "Bullet Proof Value"
            Dim SecRobot = New cSecurityRobot
            SecRobot.Name = txtName.Text
            SecRobot.Temperature = nudTemp.Value
            SecRobot.Threshold = nudThreshold.Value
            SecRobot.BulletproofValue = nudOther.Value
            thisRobot = SecRobot
        Case 1
            lblOther.Text = "Special Moves"
            Dim SpRobot = New cSportsRobot
            SpRobot.Name = txtName.Text
            SpRobot.Temperature = nudTemp.Value
            SpRobot.Threshold = nudThreshold.Value
            SpRobot.SpecialMoves = nudOther.Value
            thisRobot = SpRobot
        Case 2
            lblOther.Text = "Domestic Skills"
            Dim SerRobot = New cServiceRobot
            lblOther.Text = "Domestic Skills"
            SerRobot.Name = txtName.Text
            SerRobot.Temperature = nudTemp.Value
            SerRobot.Threshold = nudThreshold.Value
            SerRobot.DomesticSkills = nudOther.Value
            thisRobot = SerRobot
        Case Else
            lblOther.Text = "Bullet Proof Value"
            Dim SecRobot = New cSecurityRobot
            SecRobot.Name = txtName.Text
            SecRobot.Temperature = nudTemp.Value
            SecRobot.Threshold = nudThreshold.Value
            SecRobot.BulletproofValue = nudOther.Value
            thisRobot = SecRobot
    End Select
  

Форма 2 присваивает некоторые значения и завершается, но всегда возникает исключение NULL

Ответ №1:

Давайте посмотрим на ваш конструктор:

 Public Sub New(ByRef Robot As cRobot)
    InitializeComponent()
    thisRobot = Robot '<-- Problem is here
End Sub
  

В указанной выше строке вы создаете копию ссылки, и поэтому ByRef вам больше не помогает.

Думая о том, как обойти эту проблему, вы могли бы сделать это, вложив робота в другой класс:

 Public Class RobotContainer
     Public Property Robot As Robot
End Class
  

Передайте экземпляр RobotContainer вашему конструктору обычным (ByVal) способом и сохраните ссылку на весь этот объект в вашем классе. Теперь и ваш тип frmCreate, и вызывающий код имеют ссылку на один и тот же объект. Когда вы обновляете свойство робота для этого объекта, оно будет обновлено для обоих местоположений.

Но на самом деле, весь этот дизайн не пахнет правильно. Обычно я бы предложил метод, который возвращает созданного робота, вместо того, чтобы пытаться напрямую назначить его внешнему местоположению, но я понимаю, что при работе с элементами управления Windows Forms это может быть невозможно. Чтобы предложить лучшее решение, нам нужно будет просмотреть намного больше вашего кода.


Хм… оглядываясь назад, я хотел что-то сделать, чтобы сделать RobotContainer более полезным:

 Public Class ReferenceContainer(Of T)
    Public Property Item As T
End Class
  

Комментарии:

1. Привет, Джоэл — я изменил стратегию. Вместо перехода к новой форме я перегрузил OnshowDialog и передал туда ByRef, и это решило проблему (но мне это не нравится). Но, как я уже сказал, это решило проблему, так что хватит с меня жалоб. Еще раз спасибо за все ваше время. Эйден

2. PS мне очень нравится ваш подход

Ответ №2:

Нет, значение «ByRef» имеет значение только для метода, в котором объявлен параметр. Значение thisRobot переменной по-прежнему является просто ссылочным значением. Последующее изменение значения этой переменной не приведет к изменению переменной вызывающего объекта.

Комментарии:

1. Есть ли способ перенести ByRef, например (C имеет amp; operator) Спасибо

2. @AidenStrydom: Нет. Возможно, вы захотите прочитать соответствующее сообщение в блоге Эрика Липперта

3. Спасибо — изменил некоторый код — перегрузил диалоговое окно onshow и передал туда ByRef . В любом случае спасибо