.Addを使用しているときにセッターが訪問されないのはなぜですか?

コレクションが変更されたときにフラグを設定しようとしています。これを行う論理的な場所はsetterメソッドにあるようです。問題は、このコードを使用するときです

setterDemo1.Widgets.Add(new Widget)

m_widgetSetterVisitedがTrueに設定されていません。 誰かが私がここで行方不明を見ますか? ありがとう、 デイブ

Public Class SetterDemo

    Private m_Widgets As List(Of Widget) = New List(Of Widget)
    Public m_widgetSetterVisited As Boolean = False

    Public Property Widgets() As List(Of Widget)
        Get
            Return m_Widgets
        End Get
        Set(ByVal value As List(Of Widget))
            m_widgetSetterVisited = True
            m_Widgets = value
        End Set
    End Property

End Class

Public Class Widget

    Public Name As String
    Public Age As Integer

End Class
1

4 答え

あなたのコード例では、フィールド上で get を実行してから、 List 型の返されたオブジェクトに対してメソッドを呼び出しています。フィールド m_Widgets の値を設定することは決してないことに注意してください。要するに、これは機能しません。

あなたがしたいことを達成するためには、 System.Collections.ObjectModel 名前空間(またはそれが不可能な場合は List )のクラスから継承する必要があります。メンバーを追加したり削除したり、 List をカプセル化して IList を実装し、必要に応じて内部リストにディスパッチするさまざまなメソッドをオーバーライドします。また、 ObservableCollection を使用して、イベントを発生させることもできますオブジェクトは追加/削除されます。

編集 - 可能ならば System.ObjectModel.Collection を使用するギデオンのノートを無効にする

2
追加された
List は優先ベースクラスではありません(ただし、そのアプローチが必要な外部の問題があるかもしれません)。コレクションを作成するときは、 System.ObjectModel.Collection から派生する必要があります。
追加された 著者 Gideon Engelberth,
これらの優れた答えをすべて見ていただき、ありがとうございます。新しいメンバーを追加することによって、私は.Widgetsの価値を変えているので、それを書いているので、セッターが呼ばれると思ったでしょう。
追加された 著者 JollySwagman,

あなたのコードは、 List(Of Widget)自体を設定するときに、そのメンバーにアクセスするときではなく、あなたの m_widgetSetterVisited フラグを変更するだけです。したがって、このようなコードでトリガする必要があります:

setterDemo.Widgets = New List(Of Widget)

または

setterDemo.Widgets = OtherWidgetObject

Simply manipulating the members of that reference will not wまたはk.

1
追加された
私は、この答えを役に立たないとマークした人の考えに答えることに興味があります。 :)
追加された 著者 Andrew Barber,

これを処理する方法は、すべてのコレクションを System.Collectionsから継承させることです。 ObjectModel.KeyedCollection または System.Collections.ObjectModel.Collection

これらのコレクションには、コレクション内の項目が変更されたときに発生するオーバーライドされたメソッド(InsertItem、RemoveItem、ClearItems、およびSetItem)があります。

これらのメソッドのそれぞれをオーバーライドし、必要に応じてフラグを設定することができます。

1
追加された

You can use an ObservableCollection which supports the IList interface and also supports collection changed notification:

Imports System.Collections.ObjectModel
Imports System.Collections.Specialized

Public Class ChangedDemo

    Private m_Widgets As ObservableCollection(Of Widget) = New ObservableCollection(Of Widget)
    Public m_WidgetsChanged As Boolean = False

    Public Sub New()
        AddHandler m_Widgets.CollectionChanged, AddressOf m_Widgets_CollectionChanged
    End Sub

    Private Sub m_Widgets_CollectionChanged(ByVal sender As Object, ByVal e As NotifyCollectionChangedEventArgs)
        m_WidgetsChanged = True
    End Sub

    Public ReadOnly Property Widgets() As IList(Of Widget)
        Get
            Return m_Widgets
        End Get
    End Property

End Class
1
追加された