In the previous essay <.net The---of the Framework Source Research series, we studied how to implement a delegate in. Net. Today we'll look at the list of one of the most common collection classes we use in. Net.
As we all know, the list in the. NET Collection class is a sequential one-dimensional array, and unlike array, we can more easily manipulate the list type collection, such as inserting data, deleting data, sorting, and so on. NET source list is how to achieve it? Do we have other costs when we use the advantages of list versus array? What can we learn from the list source? With these questions, let's start today. NET Source Research Tour bar.
At the beginning of the study, let's look at the type definition of list. It's easy to know that the list inherits the interface of Ilist,ienumerator,icollection through the Object Browser. NET is implemented in this way:
public class list<t>: Ilist<t>, System.Collections.IList
This is not what is seen in the Object Browser, because the IList interface also inherits from the Ienumerator,icollection interface.
Next we look at the fields and constructors that the list contains:
Then we'll look at a few of the fields in the list. by private Const int _defaultcapacity = 4; We can see that the list can contain at least 4 elements by default. _ The size field is by definition the current length of the list. By accessing the List.capacity property we can get how many elements the list can currently contain. The number of elements currently contained in the list can be obtained by accessing the List.count property. So what's the difference between them? After careful study found that the original list from the growth of the implementation is so. Whenever you add an element, the list first determines the length of the _size and _items, and if it is equal, the size expands to _size+1 to _items. Length*2. For details, please see the following source code:
Looking at the code above, we find that the list does not do it by itself, but instead calls the Array.copy method. Iterate through the entire list of implementation code, we found that the list of almost all data operations, such as INSERT, delete, query, sort, check Cable and so on are implemented through the corresponding static methods in the array. I can tell from the above that "list is a wrapper over array" is correct.
We know that the list inherits the ICollection interface, and looking at its implementation, we find that the Icollection.issynchronized property returns false directly. So the list is not thread safe (with multithreading students should pay attention to it, This is different from the queue).
In. NET, traversing an array we can use two methods, one for loop, and two for foreach. The difference between the two is that one is sequential traversal and the other has nothing to do with order. NET in general array and list support these two kinds of traversal. People who have studied the iterative pattern in design pattern this time to see "sequential unrelated traversal" is not very familiar AH. The definition of an iteration pattern in design mode is:
Provides a way to iterate through the elements of an aggregation object without exposing the internal representation of that object.
That's right! The list is a. NET iterator. Strictly speaking, it is because the list implements the IEnumerator interface. Other words. NET in the general implementation of the IEnumerator interface is an iterator. Everyone in the work of the unconscious of the design pattern, is not feel very happy?!:)
Code see Finally, Discovery List also provides the Reverse () method for the inverted storage of all the elements, the implementation of the method is completely copied array.reverse, so I have to feel that Microsoft's reuse of the code to achieve the ultimate. Also found in the past actually put such a powerful thing ( Array) was lost.
Finally we look at the two list all the way (no copy array, not easy AH):
public void TrimExcess(){
int threshold = (int)(((double)_items.Length) * 0.9);
if (_size < threshold){
Capacity = _size;
}
}
public bool TrueForAll(Predicate<T> match){
if (match == null){
ThrowHelper.ThrowArgumentNullException (ExceptionArgument.match);
}
for (int i = 0; i < _size; i++){
if (!match(_items[i])){
return false;
}
}
return true;
}