다음을 통해 공유


The reason why Collection, ReadOnlyCollection, and KeyedCollection were moved to System.Collections.ObjectModel namespace

Several people asked me why Collection<T>, ReadOnlyCollection<T>, and KeyedCollection<TKey,TValue> were moved to System.Collections.ObjectModel namespace. Here are the two main reasons:

1.      Microsoft.VisualBasic namespace contains a non-generic type called Collection. The namespace is imported by default by the VB project template and we were afraid that it would confuse developers who import System.Collections.Generic namespace as well and would see two types called ‘Collection’ in their intellisense (given one of them generic, but still). We were faced with either renaming Collection<T> to something else or moving it to another namespace. We really did not want to rename it because Collection<T> is just the best name for the type (with not many good alternatives) and it will show in many APIs.

2.      We also thought that not many people will need to declare variables of thses types. Most developer who will directly use (instantiate) the collections are framework (object model) designers. Developers writing applications (majority) would simply call Directory.Files.Count for example (and not even realize it’s a Collection<FilerInfo>) or they will/should use List<T> instead. Having said that, recently I started to be concerned that some people will have to declare Collection<X> variables to cache collection instances they get from APIs, but I have not received any substantial feedback on this. BTW, this will be mitigated by many APIs actually returning subclasses of Collection<X> instead of the base class.

Some people also commented that the name “ObjectModel” is a bit “kooky” (direct quote). I have received some feedback (not much but some) about it from customers, but I think the main issue is that the term is so overloaded and many people mean many different things when they say “object model”. Anyway, we would probably try to come up with some less controversial name if we were in the design phase today, but it’s kind of late in the product cycle now to make such changes.

Comments

  • Anonymous
    March 15, 2005
    I think you should put them back into the System.Collections namespace and suffix each type with 'base'. e.g. CollectionBase<T>

  • Anonymous
    March 15, 2005
    Seems to me that you are guaranteeing that Collection<T> et al will end up in a backwater.

    Im not sure that the needs of intellisense should drive any decisions about how to structure namespaces.

    That said, if you were going to jigger the namespaces to push these classes into the background, may i suggest System.Collections.Generic.Fundamental

  • Anonymous
    March 15, 2005
    Since VB doesn't import System.Collections.Generic by default I guess I would just leave these types in System.Collections.Generic. I cringe when I hear folks make "unusual" API design choices just to accomodate Intellisense. Ew.

    OK I just tried this in the FebCTP bits. If you manually import System.Collections.ObjectModel you get this in the Intellisense list:

    Collection
    Collection(Of T)

    That doesn't seem confusing to me at all. Just put 'em back where they belong. :-)

  • Anonymous
    March 16, 2005
    Please stop punishing the rest of us for things that you assume VB people won't understand.

  • Anonymous
    March 16, 2005
    We don't want to suffix them with "Base" because they will often show in APIs and it's slightly worse to see
    public CollectionBase<FileInfo> Files { get;}
    ... than
    public Collection<FileInfo> Files { get;}.

    I do agree with the sentiment that seeing both Collection and Collection(of T) in intellisense is not bad (and I will pass this feedback to the VB team). I would presonally prefer the collection in the main namesapce myself, but I did get strong feedback from the VB team that it is a problem for many people.

    Thirdly, I have to say that I disagree that intellisense should not influence API design. Modern development platforms are APIs + Tools. They are not seperable. You need to design them together. Of course, knowing when to change APIs and when to fix tools is an important consideration. In this particular case we decided that changing the API was net better than changing the tools.

  • Anonymous
    March 16, 2005
    Well here in lies the conundrum. When you put it into a namespace like 'ObjectModel' you iply it's going to be used in someones object model. So consider a User object in a ECC design pattern style object model. You would have User, UserCollection and UserFactory. You would not have User, Collection<User>, UserFactory.

    I would mark it abstract, teach people how to inherit ala

    public class UserCollection : Collection<User>
    {}

    and drive good design. Let's face it, in an 'ObjectModel' you would strong type directly (even if it's a simple like above).

    When you consume ala Collection<User> the collection is not part of the same object model as the User (my OM). It is part of your OM and I am a consumer.

    Sometimes you people really make me wonder. Are you seriously going to muck up the netFx BCL to support backwards compat with a VB6 object?

    If you ask me you should either put it back and deprecate the VB object, or mark it abstract and force people to use it via inheritiance in 'thier' object model.

    This is just dumb...

  • Anonymous
    March 16, 2005
    The comment has been removed

  • Anonymous
    March 16, 2005
    The comment has been removed

  • Anonymous
    March 18, 2005
    How are we support sort a collection that is derived from Collection(Of t)? Since Me.InnerList doesn't exist in Collection(Of t)?

  • Anonymous
    March 19, 2005
    I think Paul is correct here. Vb already has the Type Collection, and it woudl make sense in the future if that was Collection&lt;T&gt;, whihc would indicate a type whereh the items are strongly typed and accessible by both index adn key.<br><br>ObjectModel.Colleciton&lt;T&gt; on the other hand seems to be nothign more than a class that attemtps to encapsualte List&lt;T&gt;, yet does so rather poorly as it still exposes a reference to the lists via the Items property.<br><br>Seriously I find myself asking why even have ObjectModel.Collection&lt;T&gt; when we have List&lt;T&gt;. Andto name it so as the only thing preventing a clash with a generic from of the Vb Colleciton class is by having to use namespaces, seems really silly.<br><br>$0.02<br><br><br>

  • Anonymous
    March 19, 2005
    scratch that last bit about not seeing the reasong for ObjectModel.Collection(Of T).. I thought Items was public, not protected. So that changes things a lot ;)<br><br>Still, on the other point, the potential clash with a VB Colelction class that is generic is still problematic and a rename would have been more suitable, perhaps something like SimpleList would have been more appropiate and be more self describing too when looking at the plethera of list/colleciton types to choose<br>

  • Anonymous
    March 20, 2005
    Blog link of the week 11

  • Anonymous
    March 21, 2005
    I have to agree with "Paul D. Murphy". You're about to make another poor namespace decision because of VB6, and make all of us (a number of Vb.net/C# consumers that should be GROWING at a much more substantial pace than VB6)

    Not to mention that VB6 people STILL don't use VB.Net... Why? because they like (REALLY LIKE)/understand/don't-wanna-learn-OO-VB VB6.

    Why don't you focus more on Education and documentation. For instance, push the responsibility onto the VB team. When intellisense comes up, are ya gonna show the "OLD" Microsoft.VisualBasic.Collections (which STILL use 1 based numbering) in the list? That's fine, just give the people who know "VB.NET" the correct option of System.Collections.Collection (hmmm, did the VB6 people get confused with the two "Collection" names in the namespace?)

    I urge you to reconsider such a silly idea. I urge the VB team to step up and consider modifying intellisense to cater to BOTH crowds that you continue to coddle. (IMO, the VB.Net crowd SHOULD be who you're focusing on, since they are obviously more forward thinking than the people that still start new projects in VB6 "because they dont wanna learn OO-VB")

  • Anonymous
    March 31, 2005
    The comment has been removed

  • Anonymous
    January 09, 2007
    You could just rename "ObjectModel" to "BaseClasses" since the ObjectModel just contains abstract base classes for other classes to inherit from.

  • Anonymous
    January 10, 2007
    Majority of ObjectModel collections are not abstract and in fact are often used directly.

  • Anonymous
    May 02, 2007
    I have to say that this was a truly terrible idea, for a number of reasons:

  1. "Modern development platforms are APIs + Tools. They are not seperable. You need to design them together." Yet another example of Microsoft's astonishing arrogance. Are you implying that the only way to write .NET code is to use Visual Studio? Because, guess what, its not. Design tools are an essential part of a modern development environment, yes; but the framework should be built to stand the test of ANY environment, and the specific tools which are built ON TOP OF (not alongside) that framework should conform to the framework.
  2. Please, please, PLEASE stop assuming that all Visual Basic programmers are stupid. If they don't know enough about the environment they are working in to know the difference between VisualBasic's Collection and the framework's Collection<>, that is what the MSDN is for; they can go look it up. Relegating an otherwise useful collection to a backwater namespace where no one can find it because you are afraid that a small subset of users is going to get confused is what happens when marketing people start making programming decisions.
  3. If you are afraid that people might think the two classes are related when in fact they are not, maybe that should tell you that one (or both) of the classes are misnamed. In fact, Collection<> was a horrible choice for that class. "Collection" is a general term for a structure which holds things; hence the interfaces ICollection and ICollection<>. Collection<> is actually a list; in fact, the only different between Collection<> and List<> is that Collection<> has some overridable methods for taking specific actions when the list changes. That makes Collection<> a MORE specific version of List<>, and yet it was given a LESS specific name. How did this make it out of the first round of design? Surely even the interns at Microsoft could have figured this one out? And if you were so worried about name confusion, why does the vast difference between the similarly named ICollection<> and Collection<>? I love .NET, but I am too often confounded by the obviously terrible decisions that are made by the designers (witness the forth-coming collection intializers in C# 3.0). At the very least Microsoft needs to spend more time getting community feedback on design issues in earlier stages, so that we can point out the obvious flaws before it is too late to correct them.
  • Anonymous
    May 02, 2007
    David, Thanks for your perspective. “Are you implying that the only way to write .NET code is to use Visual Studio?” No. First, we build roads because many people use cars and cars drive better on roads. The fact that we build roads does not imply that cars are the only means of transportation. Secondly, Intellisense is common in many code editors these days. “Please, please, PLEASE stop assuming that all Visual Basic programmers are stupid.” I don’t think all VB programmers are stupid. Please don’t imply that I do :-). As to the main point, I hope you are not arguing that we can make APIs arbitrarily confusing and expect that MSDN will straighten it all out. If you are just pointing out that we made a bad trade off in this case, then point taken. And, no marketing person was involved in making this decision. Could you suggest a better name for Collection<T>? We wanted a name that is short and works well in the main scenario: the type of properties. In such scenarios, the user does not care much about anything besides that the property represents a collection of something.

  • Anonymous
    June 12, 2007
    I know I'm late in here but how is the new Collection(Of T) better than CollectionBase?  There are no protected overridable methods like OnInsertComplete.  How do you write a base collection class and not include methods to hook events on for something like ObjectAdded or ObjectRemoved?   These are the basic constructs that make working with collections usable.  I have noticed that in .NET 3.0 there is an ObservableCollection that I wish was in .NET 2.0.   Generics are such a great feature to 2.0, I just wish I could use something in the framework that makes sense on collections.   Collection(Of T) doesn't even have overridable Add(), or Remove() methods that you could hook your own events to.  Instead I have to use the cheesy Shadows keyword (or new in c#).   Seems CollectionBase has more flexibiliy although when I extend it in a generic derived collection, it no longer works with the "Show As Collection Association" in the Class Diagram.

  • Anonymous
    June 12, 2007
    Dave, you should take a look at the following MSDN topic on Collection<T>: http://msdn2.microsoft.com/en-us/library/ms132397.aspx It shows how to override protected APIs to hook up events.

  • Anonymous
    June 13, 2007
    That's fine, but having a base class to do it is the whole point to me.  Bacially I might as well write my own implementation of IList(Of T) if I have to override and the functionality of Collection(Of T) anyway.  I just need to make sure I implement them correct, which saves no time.   I'll look forward to ObservableCollection in 3.0.  For now I'll stick with CollectionBase. Thanks.

  • Anonymous
    June 14, 2007
    The comment has been removed

  • Anonymous
    June 15, 2007
    The comment has been removed

  • Anonymous
    August 08, 2007
    PingBack from http://www.ugimobile.org/blogs/mighell/archive/2007/08/09/the-reason-why-collection-lt-t-gt-readonlycollection-lt-t-gt-and-keyedcollection-lt-tkey-tvalue-gt-were-moved-to-system-collections-objectmodel-namespace.aspx

  • Anonymous
    November 20, 2007
    The comment has been removed

  • Anonymous
    November 21, 2007
    The comment has been removed

  • Anonymous
    November 22, 2007
    Alright Krzysztof, let's go on an exploratory journey through the BCL as seen in C#. The following Timer classes are even exactly the same name but a namespace separation is sufficient to indicate that they are different. And indeed, they are different. Very different! System.Threading.Timer; System.Timers.Timer; System.Collections already has CollectionBase. I would have supported calling the generic version CollectionBase<T> as well, except that ClassBase seems to be a convention I'll like to reserve for abstract base classes. What does VB collection do that will be so difficult to deprecate, anyway? The only difference I see b/w the Microsoft.VisualBasic.Collection and the System.Collection.Generics.ObjectModel.Collection is that the VB collection can insert an object between two other objects.  If this is so important, implement it in the System.Collections namespace and make Collection<T> to also do it. If you ask me, a VB Collection is nearly like ArrayList. Retaining the name made sense for automatically migrating VB code in .NET 1.0 and 1.1.  Any further than that, it begins to be excess luggage like C++ inherited from C, stifling its evolution. In practice, VB migration to VB.NET has no real turn-key solution. Most of the old code requires redesign, anyway!

  • Anonymous
    December 29, 2007
    PingBack from http://cars.oneadayvitamin.info/?p=765

  • Anonymous
    February 04, 2008
    If you need a collection of objects accessed by a key, and the key is one of the object's properties, then you should use the KeyedCollection class instead of Dictionary. http://www.devtopics.com/keyedcollection-dictionary-for-values-with-embedded-keys/

  • Anonymous
    August 08, 2008
    PingBack from http://www.atalasoft.com/cs/blogs/stevehawley/archive/2008/08/08/generic-fiddling.aspx

  • Anonymous
    December 24, 2008
    OK, so I'm a bit late. But I so totally agree with Thong Nguyen (April 1, 2005 7:08 AM) that I had to express my support for what he says... "This is the lamest thing I've every heard. Could Microsoft design worse APIs?" "Collection is NOT the sensible name for a class that implements ICollection AND IList. ListCollection is the right name. Either do that or redefine ICollection and IList. " "List and Collections are abstract concepts. LinkedList, ArrayList and HashMap, TreeMap, etc are concrete concepts." Collection<> actually being an IList<>, and List<> actually being logically a vector/ArrayList, have both tripped me up. I'm sure I'm not the only one. Please, naming is one of the most important things to get right in an API.

  • Anonymous
    June 16, 2009
    PingBack from http://lowcostcarinsurances.info/story.php?id=3248