Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are C# collection-properties not flagged as obsolete when calling properties on them?

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.


Edit: I've submitted this through Microsoft Connect, issue #417159.

Edit 16.11.2010: 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?".


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.

Here's an example program, ready to compile in Visual Studio 2008.

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.

Is this a bug, or is this a "hidden gem" of the C# compiler I wasn't aware of?

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<String> 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<String> ValueList
        {
            get
            {
                return new List<String>(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<String> list = bc.ValueList;            // #4 - OK
        }
    }
}
like image 288
Lasse V. Karlsen Avatar asked Feb 23 '09 10:02

Lasse V. Karlsen


1 Answers

This is a genuine bug. Unfortunately due to a refactoring clean up that missed this case. I fixed this for the C# 4.0 compiler release coming up in VS 2010/NDP 4.0 but there are no plans to fix it now in Orcas and unfortunately there is no work around I know of to deal with this.

I hate to say it but you will need to upgrade to the NDP 4 csc.exe or VS2010 when they become available to fix this issue.

I'm thinking about posting an entry on my fresh new msdn blog about this. Makes a good anecdotal example of how refactoring can break your code.

Ian Halliday

C# Compiler SDE
Microsoft

like image 113
Ian Halliday Avatar answered Oct 29 '22 21:10

Ian Halliday