Collections in C# (The basics 3)
— C# basics — 2 min read
5. Commonly used interfaces and method implementation
The main interfaces of Collection
IEnumerable<T>
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
Collections that implement IEnumerable<T> can be enumerated by using the foreach
statement.
The foreach statement is a syntax sugar, it’s actually the MoveNext(), Current() and Reset() in IEnumerator<T> do the job.
ICollection<T>
The ICollection<T> interface extends IEnumerable<T>;IDictionary<TKey,TValue> and IList<T>are more specialized interfaces that extend ICollection<T>. A IDictionary<TKey,TValue> implementation is a collection of key/value pairs, like the Dictionary<TKey,TValue>class. A IList<T>implementation is a collection of values, and its members can be accessed by index, like the List<T>class.
Methods: Add, Clear,Contains, Copy to, Remove ( Bold represents new methods apart from the parent interface )
Uses IEquatable<T> to determine whether a instance is in the collection, or you can write your own EqualityComparer<T> to determine for a specific collection. An example will be discussed later.
IList<T>
The IList<T> generic interface is a descendant of the ICollection<T> generic interface and is the base interface of all generic lists.
Methods: IndexOf, Insert, RemoveAt ( Bold represents new methods apart from the parent interface )
While deleting a element from the IList<T>, one should use for
with a descending order instead of using foreach.
Because RemoveAt() method will change the index of other elements.
IDictionary<TKey,TValue>
The IDictionary<TKey,TValue> interface is the base interface for generic collections of key/value pairs. Each element is a key/value pair stored in a KeyValuePair<TKey,TValue> object.
Methods: ContainsKey, TryGetValue ( Bold represents new methods apart from the parent interface )
ISet<T>
This interface provides methods for implementing sets, which are collections that have unique elements and specific operations. The HashSet<T> and SortedSet<T> collections implement this interface.
Implementations can vary in how they determine equality of objects; for example, the List<T> class uses Comparer<T>.Default, whereas the Dictionary<TKey,TValue> class allows the user to specify the IComparer<T> implementation to use for comparing keys.
IComparer<T> and IEqulityComparer<T>
This interface is used with the List<T>.Sort and List<T>.BinarySearch methods. It provides a way to customize the sort order of a collection. Classes that implement this interface include the SortedDictionary<TKey,TValue> and SortedList<TKey,TValue> generic classes.
The default implementation of this interface is the Comparer<T> class. The StringComparer class implements this interface for type String.
This interface supports ordering comparisons. That is, when the Compare method returns 0, it means that two objects sort the same. Implementation of exact equality comparisons is provided by the IEqualityComparer<T> generic interface.
We recommend that you derive from the Comparer<T> class instead of implementing the IComparer<T> interface, because the Comparer<T> class provides an explicit interface implementation of the IComparer.Compare method and the Default property that gets the default comparer for the object.
Comparer is very useful in generic collections, because it’s the core of finding by key, sorting and add value by key.
With these two interface, we can customize the why of sorting data or query data by key.
You can assign a comparer implementing the interface( Icomparer or Iequalitycomparer )in constructors
1//one way of using comparer(Icomparer)2 static Dictionary<Box, String> boxes;3
4 static void Main()5 {6//Boxes equality by Dimension7 BoxSameDimensions boxDim = new BoxSameDimensions();8 boxes = new Dictionary<Box, string>(boxDim);9 Box redBox = new Box(8, 4, 8);10 Box greenBox = new Box(8, 6, 8);11 Box blueBox = new Box(8, 4, 8);12 Box yellowBox = new Box(8, 8, 8);13 AddBox(redBox, "red");14 AddBox(greenBox, "green");15 AddBox(blueBox, "blue");16 AddBox(yellowBox, "yellow");17
18//Boxes equality by volume19 BoxSameVolume boxVolume = new BoxSameVolume();20 boxes = new Dictionary<Box, string>(boxVolume);21 Box pinkBox = new Box(8, 4, 8);22 Box orangeBox = new Box(8, 6, 8);23 Box purpleBox = new Box(4, 8, 8);24 Box brownBox = new Box(8, 8, 4);25 AddBox(pinkBox, "pink");26 AddBox(orangeBox, "orange");27 AddBox(purpleBox, "purple");28 AddBox(brownBox, "brown");29 }30
31public class Box32{33 public Box(int h, int l, int w)34 {35 this.Height = h;36 this.Length = l;37 this.Width = w;38 }39 public int Height { get; set; }40 public int Length { get; set; }41 public int Width { get; set; }42}43
44class BoxSameDimensions : EqualityComparer<Box>45{46 public override bool Equals(Box b1, Box b2)47 {48 if (b1 == null && b2 == null)49 return true;50 else if (b1 == null || b2 == null)51 return false;52
53 return (b1.Height == b2.Height &&54 b1.Length == b2.Length &&55 b1.Width == b2.Width);56 }57
58 public override int GetHashCode(Box bx)59 {60 int hCode = bx.Height ^ bx.Length ^ bx.Width;61 return hCode.GetHashCode();62 }63}64
65class BoxSameVolume : EqualityComparer<Box>66{67 public override bool Equals(Box b1, Box b2)68 {69 if (b1 == null && b2 == null)70 return true;71 else if (b1 == null || b2 == null)72 return false;73
74 return (b1.Height * b1.Width * b1.Length ==75 b2.Height * b2.Width * b2.Length);76 }77
78 public override int GetHashCode(Box bx)79 {80 int hCode = bx.Height * bx.Length * bx.Width;81 return hCode.GetHashCode();82 }83}
The item class can also derive from comparer (Equalitycomparer)
1Boxes.Sort(new BoxLengthFirst());2
3public class BoxLengthFirst : Comparer<Box>4{5 // Compares by Length, Height, and Width.6 public override int Compare(Box x, Box y)7 {8 if (x.Length.CompareTo(y.Length) != 0)9 {10 return x.Length.CompareTo(y.Length);11 }12 else if (x.Height.CompareTo(y.Height) != 0)13 {14 return x.Height.CompareTo(y.Height);15 }16 else if (x.Width.CompareTo(y.Width) != 0)17 {18 return x.Width.CompareTo(y.Width);19 }20 else21 {22 return 0;23 }24 }25}26
27/***********************or***********************/28
29Boxes.Sort();30public class Box: Comparer<Box>31{32 // Compares by Length, Height, and Width.33 public override int Compare(Box x, Box y)34 {35 if (x.Length.CompareTo(y.Length) != 0)36 {37 return x.Length.CompareTo(y.Length);38 }39 else if (x.Height.CompareTo(y.Height) != 0)40 {41 return x.Height.CompareTo(y.Height);42 }43 else if (x.Width.CompareTo(y.Width) != 0)44 {45 return x.Width.CompareTo(y.Width);46 }47 else48 {49 return 0;50 }51 }52}
Collections in C# (The basics 1)
Collections in C# (The basics 2)
Collections in C# (The basics 3)