1

To begin, this question is very similar but not the same as How to call an explicitly implemented interface-method on the base class .

My problem is that I cannot even add any helper method to the base class in question to work around the issue addressed in that question.

The code:

class AsyncObservableCollection<T> : ObservableCollection<T>
{

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new ThreadSafeEnumerator<T>(this.GetEnumerator(), this.mutex);
    }
}

Where ObservableCollection<T> comes from Collection<T> which implements IEnumerable<T>.

The compile error:

AsyncObservableCollection<T>.IEnumerable<...>.GetEnumerator()': 
containing type does not implement interface 'System.Collections.Generic.IEnumerable<T>

The question:

So my aim is to have any foreach loops using an instance of my AsyncObservableCollection<T> to get my custom enumerator while allowing this.GetEnumerator() in my custom method still get the 'standard' enumerator. I'm not sure what is the best way to do this.

Community
  • 1
  • 1
user1807768
  • 687
  • 1
  • 7
  • 11

1 Answers1

2

You simply need to explicitly state that the class implements that interface. Don't rely on the fact that the base class implements it:

class AsyncObservableCollection<T> : ObservableCollection<T>, IEnumerable<T>

Having said that, as a matter of good design, I'd suggest not having the implicit interface implementation be so radically different from the other implementation. Instead you should have a method/property to get the "other" version, or possibly even both iterators, so that it is very clear for the caller when their iteration semantics are different. (On top of that, it lets users use either type of semantics with a foreach loop, instead of manually iterating the iterator just to get different semantics.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • Thanks Servy, I marked your answer as correct because it looks to be working now. I'm interested in your suggestion for best practices though; I hadn't thought about protecting users from misusing it. I really don't want the thread-unsafe 'standard' enumerator to be exposed at all. I want only the thread-safe wrapper enumerator to be publicly accessible(and used by foreach and such). Moreover, I really don't want them manually iterating the custom iterator either since they could forget to call the ThreadSafeEnumerator.Dispose() which ends the lock. I'll have to work on this some more, thanks. – user1807768 Feb 24 '14 at 20:59