From Microsoft web site:

In a generic type or method definition, a type parameter is a placeholder for a specific type that a client specifies when they create an instance of the generic type. A generic class, such as GenericList listed in Introduction to Generics, cannot be used as-is because it is not really a type; it is more like a blueprint for a type.

In my case I wanted to have two different generic list names, generated from different classes, but those classes would be inherited from one class, something like this:

  class IDName
  {
    public Guid ID;
    public string Name;
  }

  class FirstIDName: IDName { }
  class SecondIDName : IDName { }
Then I need one method to fill those classes:
public static void AddToIDName<T>(List<T> iDNameList, string name) where T : IDName, new()
{
  iDNameList.Add(new T
  {
	ID = Guid.NewGuid(),
	Name = name
  });
}

Here notice constraint "where T : IDName, new()". I needed constraint new because of line: "iDNameList.Add(new T"

Whole example:

using System;
using System.Collections.Generic;

namespace GenericList
{
  class Program
  {
    static void Main(string[] args)
    {
      List<FirstIDName> firstIDNames = new List<FirstIDName>();
      List<SecondIDName> secondIDNames = new List<SecondIDName>();

      AddToIDName(firstIDNames, "firstIDNameTestOne");
      AddToIDName(firstIDNames, "firstIDNameTestTwo");

      AddToIDName(secondIDNames, "secondIDNameTestOne");
      AddToIDName(secondIDNames, "secondIDNameTestTwo");
      AddToIDName(secondIDNames, "secondIDNameTestThree");

      Console.WriteLine("FirstIDName");
      foreach (FirstIDName firstIDName in firstIDNames)
      {
        Console.WriteLine($"id: {firstIDName.ID}, name: {firstIDName.Name}");
      }

      Console.WriteLine("SecondIDName");
      foreach (SecondIDName secondIDName in secondIDNames)
      {
        Console.WriteLine($"id: {secondIDName.ID}, name: {secondIDName.Name}");
      }

      Console.WriteLine("");
      Console.WriteLine("The end");
      Console.ReadKey();
    }

    public static void AddToIDName<T>(List<T> iDNameList, string name) where T : IDName, new()
    {
      iDNameList.Add(new T
      {
        ID = Guid.NewGuid(),
        Name = name
      });
    }
  }
}
Example of converting dictionary to IEnumerable.
using System;
using System.Collections;
using System.Collections.Generic;

namespace GetEnumerator
{
    class Program
    {
        static void Main(string[] args)
        {
            GetEnumeratorDict getEnumerator = new GetEnumeratorDict();

            foreach (KeyValuePair<int, string> getEnumeratorItem in getEnumerator)
            {
                Console.WriteLine($"getEnumeratorItem: {getEnumeratorItem}");
            }

            Console.WriteLine("Press any key ");
            Console.ReadKey();
        }
    }

    class GetEnumeratorDict : IEnumerable
    {
        readonly Dictionary<int, string> m_internalDictionary = new Dictionary<int, string>();

        public GetEnumeratorDict()
        {
            m_internalDictionary[1] = "test";
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return m_internalDictionary.GetEnumerator();
        }

    }
}
In code line:
IEnumerator IEnumerable.GetEnumerator()
{
	return m_internalDictionary.GetEnumerator();
}
You can implement your own OrderBy, something like I already explained hier. Difference between IEnumerator and IEnumerable you can read hier
I did little bit of exercise for tree structure data, since I am always struggling with it.

Example I took from my family tree. My grandfathers name was "Stanko" (same as me btw), he had three kids: my fathers name "Velimir", "Svetlana" and "Julka"
My father "Velimir" also had three kids: "Anamaria", "Stanko" and "Nikola"
His sister "Svetlana" had two kids: "Dragan" and "Dragana"
Dragan had one kid "Sanja" and "Dragana" two kids "Jovana" and "Aleksa"
Julka had no kids.
Structure in string looks like this:

"Stanko|Velimir|Anamaria"
"Stanko|Velimir|Stanko"
"Stanko|Velimir|Nikola"
"Stanko|Velimir|Anamaria|Tatjana"
"Stanko|Svetlana|Dragan"
"Stanko|Svetlana|Dragana"
"Stanko|Julka"
"Stanko|Svetlana|Dragan|Sanja"
"Stanko|Svetlana|Dragana|Jovana"
"Stanko|Svetlana|Dragana|Aleksa"
Main code:
using System.Collections.Generic;

namespace TreeExample
{
  class Program
  {


    static void Main(string[] args)
    {
      List<string> treeDescriptions = new List<string> { "Stanko|Velimir|Anamaria" };
      treeDescriptions.Add("Stanko|Velimir|Stanko");
      treeDescriptions.Add("Stanko|Velimir|Nikola");
      treeDescriptions.Add("Stanko|Velimir|Anamaria|Tatjana");
      treeDescriptions.Add("Stanko|Svetlana|Dragan");
      treeDescriptions.Add("Stanko|Svetlana|Dragana");
      treeDescriptions.Add("Stanko|Julka");
      treeDescriptions.Add("Stanko|Svetlana|Dragan|Sanja");
      treeDescriptions.Add("Stanko|Svetlana|Dragana|Jovana");
      treeDescriptions.Add("Stanko|Svetlana|Dragana|Aleksa");

      TreeMethods geni = new TreeMethods();
      TreeStructure geniStructure;

      geniStructure = geni.CreateStructure(treeDescriptions);

    }
  }
}
Class:
using System;
using System.Collections.Generic;

namespace TreeExample
{
  class TreeStructure
  {
    public string Name { get; set; }
    public List<TreeStructure> Children;
  }

  class TreeMethods
  {
    private TreeStructure CreateTree(string structure, TreeStructure parentTree)
    {
      if (string.IsNullOrWhiteSpace(structure))
      {
        return null;
      }
      else
      {
        string[] levels = structure.Split('|');
        if (levels.Length > 1)
          structure = structure.Substring(levels[0].Length + 1, structure.Length - levels[0].Length - 1);
        else
          structure = string.Empty;

        if (parentTree is null)
        {
          parentTree = new TreeStructure();
          parentTree.Name = levels[0];

          if (!string.IsNullOrWhiteSpace(structure))
          {
            parentTree.Children = new List<TreeStructure>();
            parentTree.Children.Add(CreateTree(structure, null));
          }
        }
        else if (parentTree.Children is null)
        {
          if (!string.IsNullOrWhiteSpace(structure))
          {
            parentTree.Children = new List<TreeStructure>();
            parentTree.Children.Add(CreateTree(structure, null));
          }
        }
        else
        {
          bool found = false;
          foreach (TreeStructure child in parentTree.Children)
          {
            string[] levelsChildren = structure.Split('|');

            if (!(child is null))
            {
              if (string.Equals(child.Name, levelsChildren[0], StringComparison.InvariantCultureIgnoreCase))
              {
                CreateTree(structure, child);
              }
            }
          }

          foreach (TreeStructure child in parentTree.Children)
          {
            string[] levelsChildren = structure.Split('|');
            if (!(child is null))
            {
              found = string.Equals(child.Name, levelsChildren[0], StringComparison.InvariantCultureIgnoreCase);
              if (found)
              {
                break;
              }
            }
          }

          if (!found && !string.IsNullOrWhiteSpace(structure))
          {
            parentTree.Children.Add(CreateTree(structure, null));
          }

        }
      }

      //there are no more leafs, go out
      return parentTree;
    }

    public TreeStructure CreateStructure(List<string> structures)
    {
      TreeStructure treeStructure = null;

      foreach (string structure in structures)
      {
        int level = 0;
        string[] rootChildren = structure.Split('|');

        treeStructure = CreateTree(structure, treeStructure);
      }

      return treeStructure;
    }

  }
}
This article I have mostly copy / pasted from here.

Here I've already explained how to create custom section in App.config, but now I need more complicated stuff, I need to have more attributes then just key / value pair.

Here is the example:

using System;
using System.Collections.Specialized;
using System.Configuration;

namespace CustomConfig
{
  class Program
  {
    static void Main(string[] args)
    {
      MilosevBlogConfig links = (MilosevBlogConfig)ConfigurationManager.GetSection("milosev.com");
      string homePage = ConfigurationManager.AppSettings.Get("homePage");

      Console.WriteLine("Home page: " + homePage);

      foreach (MilosevBlogCategoriesElement link in links.MilosevBlogInstances)
      {
        Console.WriteLine("Blog category: " + link.BlogCategory);
      }

      Console.WriteLine("Press any key...");
      Console.ReadKey();
    }
  }

  public class MilosevBlogCategoriesElement : ConfigurationElement
  {
    [ConfigurationProperty("BlogCategory", IsKey = true, IsRequired = true)]
    public string BlogCategory
    {
      get
      {
        return (string)base["BlogCategory"];
      }
      set
      {
        base["BlogCategory"] = value;
      }
    }
  }

  public class MilosevBlogCategoriesElementCollection : ConfigurationElementCollection
  {
    public MilosevBlogCategoriesElement this[int index]
    {
      get
      {

        return (MilosevBlogCategoriesElement)BaseGet(index);
      }
      set
      {
        if (BaseGet(index) != null)
          BaseRemoveAt(index);

        BaseAdd(index, value);
      }
    }

    protected override ConfigurationElement CreateNewElement()
    {
      return new MilosevBlogCategoriesElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
      return ((MilosevBlogCategoriesElement)element).BlogCategory;
    }
  }

  public class MilosevBlogConfig : ConfigurationSection
  {
    [ConfigurationProperty("categories")]
    [ConfigurationCollection(typeof(MilosevBlogCategoriesElementCollection))]
    public MilosevBlogCategoriesElementCollection MilosevBlogInstances
    {
      get
      {
        return (MilosevBlogCategoriesElementCollection)this["categories"];
      }
    }
  }
}
App.config should look like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <configSections>
    <section name="milosev.com" type="CustomConfig.MilosevBlogConfig, CustomConfig"></section>
  </configSections>

  <milosev.com>
    <categories>
      <add BlogCategory="csharp"/>
      <add BlogCategory="asp.net MVC"/>
    </categories>
  </milosev.com>

  <appSettings>
    <add key="homePage" value="http://milosev.com/" />
  </appSettings>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
</configuration>
POI in App.config:
  <configSections>
    <section name="milosev.com" type="CustomConfig.MilosevBlogConfig, CustomConfig"></section>
  </configSections>
Where MilosevBlogConfig looks like:
public class MilosevBlogConfig : ConfigurationSection
{
  [ConfigurationProperty("categories")]
  [ConfigurationCollection(typeof(MilosevBlogCategoriesElementCollection))]
  public MilosevBlogCategoriesElementCollection MilosevBlogInstances
  {
    get
    {
      return (MilosevBlogCategoriesElementCollection)this["categories"];
    }
  }
}
Source code you can download from here.