-2

When I call:

SynchronizedReadOnlyCollection<T>.Contains ( T, IEqualityComparer<T> )

it fails to call:

IEqualityComparer<T>.Equals(T x, T y)

I have sample code here:

https://github.com/user7251/repo1/blob/master/SynchReadOnlyList_Demo/SynchReadOnlyList_Demo/SynchronizedReadOnlyCollection_Demo.cs

It executes this line:

bool r = _order.Products.Contains ( p, Product.s_ProductByNameEqualityComparer );

So it should execute this line:

Console.Out.WriteLine ( string.Concat ( "ProductByNameEqualityComparer.Equals(){", x.Name, "}{", y.Name, "}" ) );

But it writes nothing to the console. Any ideas?

threesixnine
  • 1,733
  • 7
  • 30
  • 56
  • 3
    It would be a lot more useful if you spent a little time writing a short but complete program that isolates the problem, and include that in your post, instead of linking to an external source. – sstan Aug 28 '15 at 13:51
  • I already did that: https://github.com/user7251/repo1/tree/master/SynchReadOnlyList_Demo – user1074214 Aug 28 '15 at 13:59
  • What's wrong with linking to the code on GitHub? – user1074214 Aug 28 '15 at 14:00
  • 1
    [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask): *"don't just copy in your entire program ... Include just enough code to allow others to reproduce the problem"*, and *"but also include the code in your question itself. Not everyone can access external sites, and the links may break over time."* – sstan Aug 28 '15 at 14:13

2 Answers2

2

There are two issues with your code:

  1. The single parameter constructor of SynchronizedReadOnlyCollection<T> takes a syncRoot object, not the underlying collection, take a look at the documentation around the constructors here.

  2. Unlike other read-only collection wrappers, the SynchronizedReadOnlyCollection<T> also takes a snapshot of the provided collection rather than keeping a reference to the underlying collection, this can be seen in the source code here.

Being perfectly honest, I can't imagine ever using SynchronizedReadOnlyCollection<T>, if it maintained a reference to the underlying collection it could have some use, but as it takes a snapshot, it seems 100% useless to me, why lock around a resource which can only be read from? That and the fact it doesn't even implement IReadOnlyCollection<T>, I wouldn't bother trying to use it.

There is perhaps a use-case when deriving from this type and using the Items property to mutate the underlying collection, however I have seen no examples which do this.

Lukazoid
  • 19,016
  • 3
  • 62
  • 85
  • I incorrectly passed a List instead of an "object syncRoot". My fault, but I think the SynchronizedReadOnlyCollection ctor should not take an "object syncRoot". Instead, it should take a "Lock syncRoot" for type safety, where Lock is simply a "class Lock : object {}". Or better yet, it should use a ReaderWriterLockSlim. – user1074214 Aug 28 '15 at 14:34
  • @user1074214 The ctor with the `makeCopy` param is internal, so you can't use that. – Lukazoid Aug 28 '15 at 14:40
  • The ctor with the makeCopy param should be public. – user1074214 Aug 28 '15 at 14:43
  • It makes sense to use a ReaderWriterLockSlim because it shares the lock with code outside of the SynchronizedReadOnlyCollection. – user1074214 Aug 28 '15 at 14:48
  • @user1074214 It sounds like you would be better off implementing your own version of `SynchronizedReadOnlyCollection`, or better yet, use [`ConcurrentBag`](https://msdn.microsoft.com/en-us/library/dd381779(v=vs.110).aspx) – Lukazoid Aug 28 '15 at 14:49
  • My original plan was to develop my own version of SynchronizedReadOnlyCollection. As a first step, I started to write a demo to show the shortcoming of SynchronizedReadOnlyCollection. That demo led me to create this stackoverflow page. Thanks. – user1074214 Aug 28 '15 at 15:23
0

There are no items in Order.Products. You add items to the internal _products list but you never change _productsSol.

_productsSol = new SynchronizedReadOnlyCollection<Product> ( _products );} creates a new readonly collection with the current contents of _products which is empty. It doesn't update its contents when _products changes. It wouldn't be a read only collection if it did.

shf301
  • 31,086
  • 2
  • 52
  • 86
  • SynchronizedReadOnlyCollection has a reference to the original List. It doesn't copy the list. – user1074214 Aug 28 '15 at 14:04
  • Nope it copies the list. See the reference source for yourself. https://github.com/Microsoft/referencesource/blob/master/System.ServiceModel/System/ServiceModel/SynchronizedReadOnlyCollection.cs – shf301 Aug 28 '15 at 14:07
  • ReadOnlyCollection copies a reference to the list. It does not copy the data structure. I mistakenly assumed that SynchronizedReadOnlyCollection did the same. – user1074214 Aug 28 '15 at 18:35