Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How / Why is SyncRoot hidden on Queue<T>?

Confused and might be missing something simple..

I've got

var q = new Queue<object>();
lock (q.SyncRoot)
{
    ...
}

I get

Queue<T> does not provide a defintion for SyncRoot blah blah...

but, Queue<T> implements ICollection which defines SyncRoot as a public property.

So, first of all, why is this hidden. Second, how can you hide a property of an interface you're implementing?

like image 995
Erix Avatar asked Oct 05 '12 12:10

Erix


2 Answers

You can hide the property by implementing it explicitly:

    object MyQueue.SyncRoot { get; set; }

It is hidden because it's deprecated:

We found the SyncRoot-based synchronization APIs to be insufficiently flexible for most scenarios. The APIs allow for thread safe access to a single member of a collection. The problem is that there are numerous scenarios where you need to lock on multiple operations (for example remove one item and add another). In other words, it’s usually the code that uses a collection that wants to choose (and can actually implement) the right synchronization policy, not the collection itself. We found that SyncRoot is actually used very rarely and in cases where it is used, it actually does not add much value. In cases where it’s not used, it is just an annoyance to implementers of ICollection.

like image 108
herzmeister Avatar answered Nov 19 '22 19:11

herzmeister


It is an example of "explicit interface implementation."

When you implement an interface explicitly, you can only access that method via a reference of that type of that instance. In other words, if you cast that Queue to an ICollection, you will see the sync root member.

like image 3
Jonathon Reinhart Avatar answered Nov 19 '22 19:11

Jonathon Reinhart