title: LINQ Custom Sort
body: <p>I want an alphabetic sort with one exception.<br>
  There is a Group with a Name = "Public" and an ID = "0" that I want first.<br>
  (would rather use ID = 0)<br>
  After that then sort the rest by Name.<br>
  This does not return public first.    </p>
  
  <pre><code>public IEnumerable&lt;GroupAuthority&gt; GroupAuthoritysSorted 
  { 
     get 
     { 
         return GroupAuthoritys.OrderBy(x =&gt; x.Group.Name); 
     } 
  }
  </code></pre>
  
  <p>What I want is:</p>
  
  <pre><code>return GroupAuthoritys.Where(x =&gt; x.ID == 0)
         UNION 
         GroupAuthoritys.Where(x =&gt; x.ID &gt; 0).OrderBy(x =&gt; x.Group.Name);
  </code></pre>
  
  <p>GroupAuthority has a public property Group and Group has Public properties ID and Name.</p>
  
  <p>I used basically the accepted answer  </p>
  
  <pre><code>using System.ComponentModel;
  
  namespace SortCustom
  {
      public partial class MainWindow : Window
      {
          public MainWindow()
          {
              InitializeComponent();
              TestSort();
          }
          private void TestSort()
          {
              List&lt;CustomSort&gt; LCS = new List&lt;CustomSort&gt;();
              LCS.Add(new CustomSort(5, "sss"));
              LCS.Add(new CustomSort(6, "xxx"));
              LCS.Add(new CustomSort(4, "xxx"));
              LCS.Add(new CustomSort(3, "aaa"));
              LCS.Add(new CustomSort(7, "bbb"));
              LCS.Add(new CustomSort(0, "pub"));
              LCS.Add(new CustomSort(2, "eee"));
              LCS.Add(new CustomSort(3, "www"));
              foreach (CustomSort cs in LCS) System.Diagnostics.Debug.WriteLine(cs.Name);
              LCS.Sort();
              foreach (CustomSort cs in LCS) System.Diagnostics.Debug.WriteLine(cs.Name);
          }
      }
      public class CustomSort : Object, INotifyPropertyChanged, IComparable&lt;CustomSort&gt;
      {
          public event PropertyChangedEventHandler PropertyChanged;
          public void OnPropertyChanged(PropertyChangedEventArgs e)
          {
              if (PropertyChanged != null) PropertyChanged(this, e);
          }
          private Int16 id;
          private string name;
          public Int16 ID { get { return id; } }
          public String Name { get { return name; } }
          public int CompareTo(CustomSort obj)
          {
              if (this.ID == 0) return -1;
              if (obj == null) return 1;
              if (obj is CustomSort)
              {
                  CustomSort comp = (CustomSort)obj;
                  if (comp.ID == 0) return 1;
                  return string.Compare(this.Name, comp.Name, true);
              }
              else
              {
                  return 1;
              }
          }
          public override bool Equals(Object obj)
          {
              // Check for null values and compare run-time types.
              if (obj == null) return false;
              if (!(obj is CustomSort)) return false;
              CustomSort comp = (CustomSort)obj;
              return (comp.ID == this.ID); 
          }
          public override int GetHashCode()
          {
              return (Int32)ID;
          }
          public CustomSort(Int16 ID, String Name)
          {
              id = ID;
              name = Name;
          }
      }
  }
  </code></pre>