Just to expound on Andrei's answer and share my experience, I just went through an issue that I finally resolved using CollectionDataContract. Basically, in order to interface with a specific system, I wanted to be able to send and recieve xml of the format:
<SomeMessageList>
<Message>
<ID>blah</ID>
<data1>blah</data1>
<data2>etc.etc.</data2>
</Message>
<Message>
<ID>blah</ID>
<data1>blah</data1>
<data2>etc.etc.</data2>
</Message>
//any number of repeated <Message> here
</SomeMessageList>
However, if I used an array or a List object, the root tag was always called ArrayOfMessage. And if I created a class that held an array of Message objects (lets say called MsgList), then WCF would add that as an extra tag in the mix, which I could not find a way to get rid of. So it would have looked like:
<SomeMessageList>
<MsgList>
<Message>
<ID>blah</ID>
<data1>blah</data1>
<data2>etc.etc.</data2>
</Message>
//any number of repeated <Message> here
</MsgList>
</SomeMessageList>
So CollectionDataContract just gave me a simple way to control the name of the root list element.