title: Comparing Threads for equality
body: <p>I am looking for a way to explain that it's unreasonable to sprinkle high-level business logic with calls to ReferenceEquals().</p>
  
  <p>Here's a code snippet that I have a problem with (precondition in a method, designed to throw if we're on a wrong thread):</p>
  
  <pre><code>if (!object.ReferenceEquals(Thread.CurrentThread, RequestHandlerThread))
  </code></pre>
  
  <p>Is it reliable to write this instead:</p>
  
  <pre><code>if (Thread.CurrentThread != RequestHandlerThread)
  </code></pre>
  
  <p>I suggested to use ManagedThreadIds in the comparison based on what I commonly see in tutorials.  Adversary says that comparison for reference equality seems more object-oriented.</p>
  
  <p>Here's (roughly) what I saw in Reflector's view of System.Object with .NET 4.0.  Keep in mind that Thread class is sealed, and has no overload for operator==.</p>
  
  <pre><code>public static bool ReferenceEquals(object objA, object objB)
  {
      return (objA == objB);
  }
  
  public static bool Equals(object objA, object objB)
  {
      return (objA == objB || 
          (objA != null &amp;&amp; objB != null &amp;&amp; objA.Equals(objB)));
  }
  </code></pre>
  
  <p>Here are some basic tests, verifying operation on thread pool...  Did I miss any significant tests?</p>
  
  <pre><code>using System.Threading;
  using System.Diagnostics;
  using System.Threading.Tasks;
  
  namespace ConsoleApplicationX
  {
     class Program
     {
        static readonly Thread mainThread;
  
        static Program()
        {
           mainThread = Thread.CurrentThread;
        }
  
        static void Main(string[] args)
        {
           Thread thread = Thread.CurrentThread;
           if (thread != Thread.CurrentThread)
              Debug.Fail("");
  
           if(Thread.CurrentThread != thread)
              Debug.Fail("");
  
           if (thread != mainThread)
              Debug.Fail("");
  
           var task = Task.Factory.StartNew(() =&gt; RunOnBackground(thread));
           task.Wait();
  
           var anotherThread = new Thread(new ParameterizedThreadStart(RunInAnotherThread));
           anotherThread.Start(thread);
        }
  
        static void RunOnBackground(Thread fromInitial)
        {
           if (Thread.CurrentThread == fromInitial)
              Debug.Fail("");
  
           if (fromInitial != mainThread)
              Debug.Fail("");
        }
  
        static void RunInAnotherThread(object fromInitialAsObject)
        {
           var fromInitial = (Thread)fromInitialAsObject;
  
           if (Thread.CurrentThread == fromInitial)
              Debug.Fail("");
  
           if (fromInitial != mainThread)
              Debug.Fail("");
        }
     }
  }
  </code></pre>