无法调用受保护的基本方法

时间:2019-07-29 00:39:01

标签: inheritance f# protected

我正在尝试在F#中实现以下类(来自https://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/):

public class RangeObservableCollection<T> : ObservableCollection<T>
{
  private bool _suppressNotification = false;

  protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
  {
    if (!_suppressNotification)
      base.OnCollectionChanged(e);
  }

  public void AddRange(IEnumerable<T> list)
  {
    if (list == null)
      throw new ArgumentNullException("list");

    _suppressNotification = true;

    foreach (T item in list)
    {
      Add(item);
    }
    _suppressNotification = false;
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
  }
}

这是简单的代码,端口非常简单:

type RangeObservableCollection<'T>() =
    inherit ObservableCollection<'T>()

    let mutable suppressNotification = false

    override __.OnCollectionChanged(e: NotifyCollectionChangedEventArgs) =
        if not suppressNotification
        then base.OnCollectionChanged e

    member __.AddRange(items: 'T seq) =
        if isNull items
        then ArgumentNullException "items" |> raise

        suppressNotification <- true

        items |> Seq.iter __.Add

        suppressNotification <- false

        NotifyCollectionChangedAction.Reset
        |> NotifyCollectionChangedEventArgs
        |> __.OnCollectionChanged

但是,我在最后一行收到编译器错误,说

  

一个受保护的成员被调用或正在使用“ base”。仅在成员直接实现时才允许这样做,因为它们可以逃避其对象范围。

我可以找到的唯一对该错误的引用是this问题;但是,那里的解决方案似乎不适用于这里,因为我不处理事件。

所以,我的问题分为两个部分:

  • 在语言/编译器方面,这里的实际问题是什么?
  • 有没有解决的办法,还是无法在F#中实现?

1 个答案:

答案 0 :(得分:1)

如果您将最后三行更改为立即调用OnCollectionChanged,则可以:

__.OnCollectionChanged(NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))

我认为问题在于__.OnCollectionChanged本身(即,如果没有立即调用)会生成对函数的引用,该引用可能会从类的上下文中逸出。 (并非在此示例中可以,但是通过F#用来确定的简单规则,编译器无法排除它。)