TeaDrivenDev
TeaDrivenDev

Reputation: 6629

Unable to call protected base method

I am trying to implement the following class (from https://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/) in F#:

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));
  }
}

This is simple code, and the port is very straightforward:

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

However, I am getting a compiler error at the very last line, saying

A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope.

The only other reference to that error I could find is this question; however, the solution there does not seem to be applicable here, as I am not dealing with events.

So, my question has two parts:

Upvotes: 0

Views: 55

Answers (1)

Mankarse
Mankarse

Reputation: 40613

If you change the last three lines to immediately call OnCollectionChanged, it works:

__.OnCollectionChanged(NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))

I think the problem is that __.OnCollectionChanged by itself (i.e. if not immediately called) produces a reference to a function, which could escape from the context of the class. (Not that it can in this example, but by the simple rules F# uses to determine this, the compiler can't rule it out).

Upvotes: 1

Related Questions