Q1 Why do new classes from .NET implement interfaces only partially?
Q2 Shall I do the same in my code?
I asked this question here, so I thought, okay that was long time ago, you can have different usage etc etc, and now such implementation is supported only for consistency reasons. But new classes also do that.
Old
int[] list = new int[] {};
IList iList = (IList)list;
ilist.Add(1); //exception here
New
ICollection c = new ConcurrentQueue<int>();
var root = c.SyncRoot; //exception here
UPDATE
I am not worried why I get exceptions, it is clear. But I don’t understand why classes implement the well defined contract, but not all the members (which can lead to unpleasant run time exceptions)?
You could argue that the interfaces weren’t granular enough in the original design. For example, most people never use
SyncRoot– it could perhaps have been on a different interface. Likewise, it is unfortunate that no interface offers read-only indexer access, for example.As it stands, the interfaces are what they are. It is still very convenient to implement the main
IList[<T>]/ICollection[<T>]/IEnumerable[<T>]interfaces though – it offers the majority of callers access to what they need… so indexers in the first example, andAddin the second.To be fair, they do also offer
IsFixedSizeandIsReadOnly– querying the first would have led you to not callAdd. ReSyncRoot– that presumably can’t make sense insideConcurrentQueue<T>, and any implementation would break the logic of the type. Normally I would say “then it isn’t that type; don’t implement the interface”, but to repeat my earlier statement… most people never useSyncRoot– so I’m OK with it ;p