StringDictionary does not implement either ICollection or IDictionary?

  • Thread starter Thread starter Sanjay Vyas
  • Start date Start date
S

Sanjay Vyas

This is rather unusual as we would expect any Collection class to implement
ICollection interface and furthermore a Dictionary class should implement
IDictionary interface. The StringDictionary class does implements all the
methods of ICollection and IDictionary yet it does not list these
interfaces. Am I missing something here or was it an oversight on the part
of the class developer. Maybe I have attained the .NET nirvana yet?

Sanjay Vyas
 
You're right: one would expect so. But if you think a little bit further:
the IDictionary interface has an Add function that accepts two objects (key
and value). The StringDictionary class implements an Add function that
accepts two string values. So if the StringDictionary class would implement
the IDictionary interface, it couldn't enforce type safe operations, since
you'd could pass anything to the Add method.

Makes this sense to you?

--
Greetz

Jan Tielens
________________________________
Read my weblog: http://weblogs.asp.net/jan
 
Jan Tielens said:
You're right: one would expect so. But if you think a little bit further:
the IDictionary interface has an Add function that accepts two objects (key
and value). The StringDictionary class implements an Add function that
accepts two string values. So if the StringDictionary class would implement
the IDictionary interface, it couldn't enforce type safe operations, since
you'd could pass anything to the Add method.

Makes this sense to you?

I don't quite buy this - because the same could be argued for
CollectionBase which is specifically designed to be strongly-typed and
yet implements ICollection. There at least seems to be a disparity
here.
 
Hi,
I agree with Jon as StringCollection implements ICollection and yet the
Add(string value) method is a type safe implementation. The
ICollection.Add(object obj) method could be implemented explicitly?
 
Jon

The ICollection doesn't have the default property (Item in VB.NET)
implemented, nor the type-safe Add method. So I don't see the problem
there...

--
Greetz

Jan Tielens
________________________________
Read my weblog: http://weblogs.asp.net/jan
 
Jan Tielens said:
The ICollection doesn't have the default property (Item in VB.NET)
implemented, nor the type-safe Add method. So I don't see the problem
there...

Whoops, you're entirely right. However, CollectionBase *also*
implements IList, which does have those members.

It also means there's even less reason why StringDictionary shouldn't
implement ICollection.
 
Sanjay Vyas said:
Is there a way to find out from Someone[MSFT] ?

Hmmm... in theory I could find a contact at MS, I believe - but is this
actually causing you a problem, or are you just interested? (I don't
like to take *relatively* trivial things to MS myself.)
 
Hi,
Not a *big* problem, but I was implementing a class where I was poylmorphing
over the Dictionary classes.

Does Eric Gunnerson still run "ask the designer" column ?

Jon Skeet said:
Sanjay Vyas said:
Is there a way to find out from Someone[MSFT] ?

Hmmm... in theory I could find a contact at MS, I believe - but is this
actually causing you a problem, or are you just interested? (I don't
like to take *relatively* trivial things to MS myself.)
 
Sanjay Vyas said:
Not a *big* problem, but I was implementing a class where I was poylmorphing
over the Dictionary classes.

Does Eric Gunnerson still run "ask the designer" column ?

I don't know, but he certainly reads some of the newsgroups, possibly
including this one. If he's anything like me, the mention of his name
will highlight a post, so he may well have seen this :)

(On the other hand, Eric is more to do with the design of the C#
language, not the libraries.)
 
Hello!

StringDictionary stores its data internally in a HashTable instance. For a
"foreach" enumeration, StringDictionary's GetEnumerator actually uses the
HashTable Enumerator to do the enumeration and return the values to the
caller.

It might "seem" that its implementing all the methods of the ICollection and
IDictionary, but maybe that's just it: those methods are actually the
class's own and not implemented for an interface.

That said, the Keys and Values property do return ICollection.

Does that help?

--
Regards,
Kumar Gaurav Khanna
-----------------------------------------------------------------
Microsoft MVP - C#/.NET, MCSE Windows 2000/NT4, MCP+I
WinToolZone - Spelunking Microsoft Technologies
http://www.wintoolzone.com/
OpSupport - Spelunking Rotor
http://opsupport.sscli.net/
Bangalore .NET Users' Group
http://groups.msn.com/bdotnet/
 
Gaurav Khanna said:
StringDictionary stores its data internally in a HashTable instance. For a
"foreach" enumeration, StringDictionary's GetEnumerator actually uses the
HashTable Enumerator to do the enumeration and return the values to the
caller.

It might "seem" that its implementing all the methods of the ICollection and
IDictionary, but maybe that's just it: those methods are actually the
class's own and not implemented for an interface.

But the question is *why* StringDictionary doesn't claim to implement
ICollection and IDictionary. It's inconsistent with CollectionBase
implementing ICollection and IList.
 
Hi Jon!

Thats a design question that maybe the FCL designer's can answer the best.

My take on this is that why are we expecting it to be having ICollection and
IDictionary implemented directly? Aren't there other ways to do it? Maybe
thats what has happed here...

--
Regards,
Kumar Gaurav Khanna
-----------------------------------------------------------------
Microsoft MVP - C#/.NET, MCSE Windows 2000/NT4, MCP+I
WinToolZone - Spelunking Microsoft Technologies
http://www.wintoolzone.com/
OpSupport - Spelunking Rotor
http://opsupport.sscli.net/
Bangalore .NET Users' Group
http://groups.msn.com/bdotnet/
 
Well Gaurav, I AM expecting IDcitionary becuase its SringDictionary. Going
by your question, why do *any* of the other collection classes have
ICollection/IDictionary?
If its a Dictionary class, I would expect to extract IDictionary interface
and call it polymorphically.

Sanjay Vyas

Gaurav Khanna said:
Hi Jon!

Thats a design question that maybe the FCL designer's can answer the best.

My take on this is that why are we expecting it to be having ICollection and
IDictionary implemented directly? Aren't there other ways to do it? Maybe
thats what has happed here...

--
Regards,
Kumar Gaurav Khanna
-----------------------------------------------------------------
Microsoft MVP - C#/.NET, MCSE Windows 2000/NT4, MCP+I
WinToolZone - Spelunking Microsoft Technologies
http://www.wintoolzone.com/
OpSupport - Spelunking Rotor
http://opsupport.sscli.net/
Bangalore .NET Users' Group
http://groups.msn.com/bdotnet/
For
ICollection
 
The StringCollection cannot implement IDictionary because it doesn't fulfill
the interface contract. The interface is defined in terms of Object while
StringCollection only takes String as datatype.
This isn't a problem for consumers of the class getting things out of the
collection, but for those who are putting things in the collection, this
becomes a large problem.

Willy.

Sanjay Vyas said:
Hi,
I agree with Jon as StringCollection implements ICollection and yet the
Add(string value) method is a type safe implementation. The
ICollection.Add(object obj) method could be implemented explicitly?
 
Willy Denoyette said:
The StringCollection cannot implement IDictionary because it doesn't fulfill
the interface contract. The interface is defined in terms of Object while
StringCollection only takes String as datatype.

But it *could* implement IDictionary in the same way that
CollectionBase does, with the general version forwarding to the
specific version (and complaining if a non-string key/value was given).
This isn't a problem for consumers of the class getting things out of the
collection, but for those who are putting things in the collection, this
becomes a large problem.

Actually, I'd say it *is* a problem for consumers of the class getting
things out of the collection - if that consumer can deal with *any*
IDictionary (via GetEnumerator) but has to have special code for
StringDictionary :(
 
Jon,
See inline ***

Jon Skeet said:
But it *could* implement IDictionary in the same way that
CollectionBase does, with the general version forwarding to the
specific version (and complaining if a non-string key/value was given).

Yes, complaining, but how? Throwing an exception? tell me which one.

More specificaly take a look at the IDictionary::Add method, you are only
supposed to throw NotSupportedException under two well defined conditions
and "your complain" isn't one of these.

Also, don't forget throwing an undocumented exception is also breaking the
contract. But I'm sure you know his one too :-))

Willy.
 
Willy Denoyette said:
Yes, complaining, but how? Throwing an exception? tell me which one.

The same one CollectionBase throws when its given a duff value -
ArgumentException as given in the example (in OnValidate). (But not
documented, interestingly enough.)
More specificaly take a look at the IDictionary::Add method, you are only
supposed to throw NotSupportedException under two well defined conditions
and "your complain" isn't one of these.

Also, don't forget throwing an undocumented exception is also breaking the
contract. But I'm sure you know his one too :-))

Absolutely - but it looks like other things are already breaking this
contract. That's one of the downsides of not having checked exceptions
- it allows things like this to go unnoticed. Basically this side of
things is a mess, but it's made an *inconsistent* mess by
StringDictionary not implementing IDictionary, IMO.
 
Jon Skeet said:
The same one CollectionBase throws when its given a duff value -
ArgumentException as given in the example (in OnValidate). (But not
documented, interestingly enough.)

Hmm, the default OnValidate throws ArgumentNullException as is documented,
not sure which sample you are refering to. Also, IMO, OnValidate is not part
of any interface contract.

Willy.
 
Willy Denoyette said:
Hmm, the default OnValidate throws ArgumentNullException as is documented,
not sure which sample you are refering to.

The sample code for OnValidate in "about CollectionBase":

<quote>
protected override void OnValidate( Object value ) {
if ( value.GetType() != Type.GetType("System.Int16") )
throw new ArgumentException( "value must be of type Int16.",
"value" );
}
Also, IMO, OnValidate is not part of any interface contract.

Indeed - but I believe it's called as part of CollectionBase's
implementation of IList.Add. (Otherwise there's nothing to make sure
it's all valid.)

In other words, if you use the CollectionBase example, you end up with
a violation of the IList interface in terms of exceptions thrown by
Add.
 
Back
Top