Почему свойство Default получает доступ к установщику при удалении элемента - PullRequest
0 голосов
/ 12 июня 2018

В приведенном ниже коде при попытке удалить элемент из списка Cases код разрывается в установщике с индексом за пределами.При запуске отладчика в VisualStudio 2017 он успешно проходит через функцию Remove() и удаляет последний элемент, но после возврата к Main() он прерывается на сеттере, и стек вызовов сообщает, что он поступил из вызова Remove.Пример кода ниже:

Sub Main()
    Dim Cases As Collection = New Collection()
    Dim caseIndex As Integer = 2
    Cases.Remove(Cases(caseIndex))
End Sub

Public Class Collection

    Public WithEvents Cases As List(Of CaseClass)

    Public Sub New()
        Cases = New List(Of CaseClass)()
        Cases.Add(New CaseClass)
        Cases.Add(New CaseClass)
        Cases.Add(New CaseClass)
    End Sub

    Default Public Property BeltCase(ByVal Index As Integer) As CaseClass
        Get
            Return Cases(Index)
        End Get
        Set(ByVal Value As CaseClass)
            Cases(Index) = Value
        End Set
    End Property

    Public Sub Remove(ByRef BeltCase As CaseClass)
        Cases.Remove(BeltCase)
    End Sub
End Class

Public Class CaseClass
    Public test As Int16
End Class

Стек вызовов:

TestingVBBug.exe! TestingVBBug.Module1.Collection.set_BeltCase (целочисленный индекс, значение TestingVBBug.Module1.CaseClass) Строка 25 BasicTestingVBBug.exe! TestingVBBug.Module1.Main () Строка 6 Basic

Так зачем нам вообще проходить через Setter.И почему это происходит после выхода из функции удаления?

1 Ответ

0 голосов
/ 12 июня 2018

Проблема вызвана вашим Remove() методом, то есть у вас есть ByRef параметр (по какой-то причине) .При использовании ByRef любые изменения, внесенные в параметр внутри метода, должны отражаться в переменной, которая была передана в метод.Это происходит путем переназначения значения на исходную переменную.

В вашем случае это работает так:

  • Вызван метод Remove() иему передается переменная (Cases(caseIndex)).
  • Некоторая работа выполняется внутри метода Remove(), который может или не включать изменение значения параметра BeltCase.
  • Значение параметра BeltCase переназначается переменной, которая первоначально была передана методу (то есть Cases(caseIndex)) .
  • В результатеНа предыдущем шаге установщик свойства BeltCase вызывается с Index = 2, что вызывает исключение вне диапазона, поскольку Cases(2) не существует (был удален).

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

Cases.Remove(Cases(caseIndex))

.. на:

Dim myCase As CaseClass = Cases(caseIndex)
Cases.Remove(myCase)

Таким образом, вы создадите новую переменную, которая ссылается на тот же CaseClass object и самое главное избегайте вызова установщика вашего свойства Collection.BeltClase.

HoВ любом случае, лучшим решением было бы не использовать ByRef, во-первых, , поскольку в этой ситуации он вам, кажется, не нужен .Итак, просто используйте Public Sub Remove(ByVal BeltCase As CaseClass).

Проверьте этот вопрос , чтобы узнать больше о ByVal и ByRef с объектами.

И последнее, пожалуйста, не делайтеТвой класс Collection, потому что это может смутить любого, кто смотрит на твой проект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...