title: Why are C# collection-properties not flagged as obsolete when calling properties on them?
body: <p>I tried to flag a collection property on a class as Obsolete to find all the occurances and keep a shrinking list of things to fix in my warning-list, due to the fact that we need to replace this collection property with something else.</p>
  
  <hr>
  
  <p><strong>Edit</strong>: I've submitted this through Microsoft Connect, <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=417159" rel="noreferrer">issue #417159</a>.</p>
  
  <p><strong>Edit 16.11.2010</strong>: Verified that this now works in the C# 4.0 compiler, both when compiling for .NET 3.5 and 4.0. I get 4 warnings in the posted code, including the one with the comment "Not OK?".</p>
  
  <hr>
  
  <p>However, to my surprise, the list only contained a few occurances, far fewer than I knew there were, and spotchecks tells me that for some reason, the usage of the property isn't always flagged as obsolete by the compiler in the warning list.</p>
  
  <p>Here's an example program, ready to compile in Visual Studio 2008.</p>
  
  <p>Note the four lines near the end tagged with #1-#4, of these, I'd expect all of them to report that the property used was obsolete, but #3 isn't, and it seems that if I just move on to the collection properties or methods directly, the usage of the property itself isn't flagged as obsolete. Note that #3 and #4 is referencing the same property, and #4 is flagged as using an obsolete property, whereas #3 isn't. Tests shows that if, in the expression, I access properties or methods of the collection the property returns, the compiler doesn't complain.</p>
  
  <p>Is this a bug, or is this a "hidden gem" of the C# compiler I wasn't aware of?</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  
  namespace TestApp
  {
      public abstract class BaseClass
      {
          [Obsolete]
          public abstract String Value
          {
              get;
          }
  
          [Obsolete]
          public abstract String[] ValueArray
          {
              get;
          }
  
          [Obsolete]
          public abstract List&lt;String&gt; ValueList
          {
              get;
          }
      }
  
      public class DerivedClass : BaseClass
      {
          [Obsolete]
          public override String Value
          {
              get
              {
                  return "Test";
              }
          }
  
          [Obsolete]
          public override String[] ValueArray
          {
              get
              {
                  return new[] { "A", "B" };
              }
          }
  
          [Obsolete]
          public override List&lt;String&gt; ValueList
          {
              get
              {
                  return new List&lt;String&gt;(new[] { "A", "B" });
              }
          }
      }
  
      public class Program
      {
          public static void Main(String[] args)
          {
              BaseClass bc = new DerivedClass();
              Console.Out.WriteLine(bc.Value);             // #1 - OK
              Console.Out.WriteLine(bc.ValueArray.Length); // #2 - OK
              Console.Out.WriteLine(bc.ValueList.Count);   // #3 - Not OK?
              List&lt;String&gt; list = bc.ValueList;            // #4 - OK
          }
      }
  }
  </code></pre>