Collections

IEnumerable and IEnumerator

IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface.
This works for readonly access to a collection that implements that IEnumerable can be used with a foreach statement.
IEnumerator has two methods MoveNext and Reset. It also has a property called Current

class Demo : IEnumerable, IEnumerator {
   // IEnumerable method GetEnumerator()
   IEnumerator IEnumerable.GetEnumerator() {
      throw new NotImplementedException();
   }
   public object Current {
      get { throw new NotImplementedException(); }
   }
   // IEnumertor method
   public bool MoveNext() {
      throw new NotImplementedException();
   }
   // IEnumertor method
      public void Reset() {
      throw new NotImplementedException();
   }
}

List<T> collection

List<T> uses an array to store the elements. When the number of elements exceeds the size of the array, a new and larger array is allocated, and the content of the previous array is copied to the new one. 

var numbers = new List<int> {1, 2, 3}; // 1 2 3
numbers.Add(5);                        // 1 2 3 5
numbers.AddRange(new int[] { 7, 11 }); // 1 2 3 5 7 11
numbers.Insert(5, 1);                  // 1 2 3 5 7 1 11
numbers.Insert(5, 1);                  // 1 2 3 5 7 1 1 11
numbers.InsertRange(                   // 1 13 17 19 2 3 5..
    1, new int[] {13, 17, 19});        // ..7 1 1 11

numbers.Remove(1);              // 13 17 19  2  3  5  7  1  
                                // 1 11
numbers.RemoveRange(2, 3);      // 13 17  5  7  1  1 11
numbers.RemoveAll(e => e < 10); // 13 17 11
numbers.RemoveAt(1);            // 13 11
numbers.Clear();                // empty

var numbers = new List<int> { 1, 2, 3, 5, 7, 11 };
var a = numbers.Find(e => e < 10);      // 1
var b = numbers.FindLast(e => e < 10);  // 7
var c = numbers.FindAll(e => e < 10);   // 1 2 3 5 7

var numbers = new List<int> { 1, 1, 2, 3, 5, 8, 11 };
var a = numbers.FindIndex(e => e < 10);     // 0
var b = numbers.FindLastIndex(e => e < 10); // 5
var c = numbers.IndexOf(5);                 // 4
var d = numbers.LastIndexOf(1);             // 1
var e = numbers.BinarySearch(8);            // 5

var numbers = new List<int> { 1, 5, 3, 11, 8, 1, 2 };
numbers.Sort();     // 1 1 2 3 5 8 11
numbers.Reverse();  // 11 8 5 3 2 1 1

Sort() sorts the list according to a default or specified criteria. There are several overloads that allow us to specify either a comparison delegate or an IComparer<T> object, or even a sub-range of the list to sort. This operation is performed in O(n log n) in most cases but O (n2) in the worst-case scenario.

The Dictionary<TKey, TValue> collection

var languages = new Dictionary<int, string>()
{
    {1, "C#"}, 
    {2, "Java"}, 
    {3, "Python"}, 
    {4, "C++"}
};
languages.Add(5, "JavaScript");
languages.TryAdd(5, "JavaScript");
languages[6] = "F#";
languages[5] = "TypeScript";
Console.WriteLine($"Has 5: {languages.ContainsKey(5)}");
Console.WriteLine($"Has C#: {languages.ContainsValue("C#")}");

We can also iterate through the elements of a dictionary using an enumerator, in which case the key-value pairs are retrieved as KeyValuePair<TKey, TValue> objects:

foreach(var kvp in languages)
{
    Console.WriteLine($"[{kvp.Key}] = {kvp.Value}");
}

LINQ

class A : IComparable
{
    public int value{get;private set;}
    public A(int v)=>this.value = v;
    public int CompareTo(object obj) => this.value - (obj as A).value;
}


List<A> values2 = new List<A> { new A(v:34), new A(v: 45), new A(v: 76), new A(v: 23), new A(v: 54), new A(v: 33), new A(v: 65),new A(v:33), new A(v:23) };
var res = from x in values2 where x.value>50 orderby x ascending select x;
foreach(A v in res){ Console.WriteLine(v.value);}

var res = from x in values2 group x by x.value into gg where gg.Key>30  orderby gg.Key ascending select gg.Key ;
foreach(var v in res){ Console.WriteLine(v);}//33,34,45.....
int[] arr=new int[]{1,23,21,4,34,21,44,2,31,53,21,123};
var res323=arr.TakeLast(3).OrderBy(x=>x).Distinct().Zip( arr.TakeLast(3), (x,y)=>(x,y));

foreach (var (x,y) in res323)
{
    Console.WriteLine(x+" "+y);
}