WithEvents LinkedList 不可能吗?

发布于 2024-08-24 04:01:39 字数 1525 浏览 5 评论 0 原文

WithEvents Collection - VB.NET 的最佳方法是什么?

您对下面的代码有什么评论吗(跳过 Nothing 验证)?

问题是当我在 For Each 块中获取 LinkedListNode(Of Foo) 时,我可以设置 myNode.Value = some,这是一个处理程序泄漏...

- 在这种情况下我可以重写 FooCollection 的 GetEnumerator 吗?
-不。 :( 导致 NotInheritable Class LinkedListNode(Of T)

Class Foo
  Public Event SelectedChanged As EventHandler
End Class

Class FooCollection
  Inherits LinkedList(Of Foo)
  Public Event SelectedChanged As EventHandler

  Protected Overloads Sub AddFirst(ByVal item As Foo)
    AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
    MyBase.AddFirst(item)
  End Sub

  Protected Overloads Sub AddLast(ByVal item As Foo)
    AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
    MyBase.AddLast(item)
  End Sub

  ' ------------------- '

  Protected Overloads Sub RemoveFirst()
    RemoveHandler MyBase.First.Value.SelectedChanged, _
                         AddressOf OnSelectedChanged
    MyBase.RemoveFirst()
  End Sub

  Protected Overloads Sub RemoveLast(ByVal item As Foo)
    RemoveHandler MyBase.Last.Value.SelectedChanged, _
                        AddressOf OnSelectedChanged
    MyBase.RemoveLast()
  End Sub

  ' ------------------- '

  Protected Sub OnSelectedChanged(ByVal sender As Object, ByVal e As EventArgs)
    RaiseEvent SelectedChanged(sender, e)
  End Sub
End Class

What is the optimal approach to a WithEvents Collection - VB.NET?

Have you any remarks on the code bellow (skipping the Nothing verifications)?

The problem is when I obtain the LinkedListNode(Of Foo) in a For Each block I can set
myNode.Value = something, and here is a handlers leak...

-Could I override the FooCollection's GetEnumerator in this case?
-No. :( cause NotInheritable Class LinkedListNode(Of T)

Class Foo
  Public Event SelectedChanged As EventHandler
End Class

Class FooCollection
  Inherits LinkedList(Of Foo)
  Public Event SelectedChanged As EventHandler

  Protected Overloads Sub AddFirst(ByVal item As Foo)
    AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
    MyBase.AddFirst(item)
  End Sub

  Protected Overloads Sub AddLast(ByVal item As Foo)
    AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
    MyBase.AddLast(item)
  End Sub

  ' ------------------- '

  Protected Overloads Sub RemoveFirst()
    RemoveHandler MyBase.First.Value.SelectedChanged, _
                         AddressOf OnSelectedChanged
    MyBase.RemoveFirst()
  End Sub

  Protected Overloads Sub RemoveLast(ByVal item As Foo)
    RemoveHandler MyBase.Last.Value.SelectedChanged, _
                        AddressOf OnSelectedChanged
    MyBase.RemoveLast()
  End Sub

  ' ------------------- '

  Protected Sub OnSelectedChanged(ByVal sender As Object, ByVal e As EventArgs)
    RaiseEvent SelectedChanged(sender, e)
  End Sub
End Class

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔少女心 2024-08-31 04:01:39

主要问题是您无法正确重写 GetEnumerator 函数。在这种情况下,我将创建一个不直接从 LinkedList 继承而仅使用一个作为私有字段的类:

Class FooCollection
    Implements ICollection(Of Foo)

    Private list As New LinkedList(Of Foo)

    Public Sub AddFirst(ByVal item As Foo)
        AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
        list.AddFisrt(item)
    End Sub

    ...

End Class

它将需要更多的编码,因为您需要实现所有功能,而不仅仅是您想要覆盖的功能,但是实施很简单。

The main problem is that you can't override the GetEnumerator function properly. In such case I would create a class that doesn't directly inherit from LinkedList but only uses one as a private field:

Class FooCollection
    Implements ICollection(Of Foo)

    Private list As New LinkedList(Of Foo)

    Public Sub AddFirst(ByVal item As Foo)
        AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
        list.AddFisrt(item)
    End Sub

    ...

End Class

It will require a little more coding because you need to implement all the functions instead of just the ones you want to override but the implementation is trivial.

夏日浅笑〃 2024-08-31 04:01:39

您看过CollectionChangedEventManager吗?我今天在处理队列更改时刚刚遇到了这个问题。

Have you looked at CollectionChangedEventManager? I just ran across this today when looking to deal with queue changes.

莫相离 2024-08-31 04:01:39

据我了解,没有简单的解决方案,因为集合仅保存对对象的引用,因此无法知道集合所保存的对象的属性是否已更改。

一般来说,您必须选择:

1:) 您让集合中的对象控制触发事件。您可以在 Charles Petzold 的这篇 MSDN 文章中找到示例实现。他定义了一个“ObservableNotificCollection”。

2:) 如果集合所保存的类型不受您的控制(因此您无法自己实现 PropertyChangedEvent),则可以使用代理对象。您可以在这里找到示例实现:“使用 Castle.DynamicProxy 实现 InotifyPropertyChanged"。

As I understand, there is no easy solution because the collection just holds references to the ocjects and has therefore no way to know, if a property of an object the collection holds has changed.

In general you have to options:

1:) You let the objects your collection controls fire events. A sample implementation you find in this MSDN article from Charles Petzold. He defines a "ObservableNotifiableCollection".

2:) If the types the collection holds are not at your control (so you can't implement a PropertyChangedEvent yourself), you could use a proxy objects. A sample implementation you can find here: "Implement InotifyPropertyChanged with Castle.DynamicProxy".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文