title: why is this generic not resolved at compile time?
body: <p>I have the following code. I expect it to print:</p>
  
  <pre><code>A
  B
  C
  DONE
  </code></pre>
  
  <p>instead it prints</p>
  
  <pre><code>P
  P
  P
  DONE
  </code></pre>
  
  <p>why?</p>
  
  <p><strong>UPDATE</strong><br>
  I'm not asking for a work around solution. I want to know why this is happening. I thought generics were resolved at compile time. From what I can tell it should be able to resolve these to the proper methods at compile time, but apparently it is not and I do not understand why. I am looking for an explanation of why, not a work around solution.</p>
  
  <p>here is the code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  
  namespace ConsoleApplication50
  {
      class Parent
      {
          public string FieldName { get; set; }
          public string Id { get; set; }
      }
  
      class ChildA : Parent
      {
          public string FieldValue { get; set; }
      }
  
      class ChildB : Parent
      {
          public DateTime? Start { get; set; }
          public DateTime? End { get; set; }
      }
  
      class ChildC : Parent
      {
          public ICollection&lt;string&gt; Values { get; set; }
      }
      class Program
      {
          void Validate&lt;T&gt;(Parent item) where T : Parent
          {
              if (item is T)
                  Validate(item as T);
          }
          void Validate(ChildA filter)
          {
              Console.WriteLine("A");
          }
  
          void Validate(ChildB filter)
          {
              Console.WriteLine("B");
          }
  
          void Validate(ChildC filter)
          {
              Console.WriteLine("C");
          }
  
          void Validate(Parent filter)
          {
              Console.WriteLine("P");
              // do nothing placeholder so the code will compile
          }
  
          ArgumentException Fail(Parent filter, string message)
          {
              return new ArgumentException(message, filter.FieldName);
          }
  
          void Run()
          {
              var list = new List&lt;Parent&gt; {
                  new ChildA(), new ChildB(), new ChildC() };
              Validate&lt;ChildA&gt;(list[0]);
              Validate&lt;ChildB&gt;(list[1]);
              Validate&lt;ChildC&gt;(list[2]);
          }
          public static void Main()
          {
              new Program().Run();
              Console.WriteLine();
              Console.WriteLine("DONE");
              Console.ReadLine();
          }
      }
  }
  </code></pre>