为什么C#collection-properties在调用它们的属性时没有被标记为过时?

时间:2009-02-23 10:19:41

标签: c# properties obsolete

我尝试将类上的集合属性标记为Obsolete以查找所有出现并在我的警告列表中保留要修复的缩减列表,因为我们需要将此集合属性替换为其他内容


修改:我是通过Microsoft Connect issue #417159提交的。

编辑16.11.2010 :在编译.NET 3.5和4.0时,验证现在可以在C#4.0编译器中使用。我在发布的代码中收到4个警告,包括评论为“不正常?”的警告。


然而,令我惊讶的是,这个列表只包含了一些内容,远远少于我所知道的,并且spotcheck告诉我,由于某些原因,编译器中的属性的使用并不总是被标记为过时。警告清单。

这是一个示例程序,可以在Visual Studio 2008中编译。

注意标记为#1-#4的末尾附近的四行,其中,我希望所有人都报告所使用的属性已过时,但#3不是,而且似乎如果我只是直接转到集合属性或方法,属性本身的使用不会被标记为过时。请注意,#3和#4引用相同的属性,#4标记为使用过时的属性,而#3则不是。测试显示,如果在表达式中,我访问属性返回的集合的属性或方法,编译器不会抱怨。

这是一个错误,还是我不知道的C#编译器的“隐藏的宝石”?

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
        }
    }
}

3 个答案:

答案 0 :(得分:18)

这是一个真正的错误。不幸的是,由于重构清理错过了这种情况。我为VS 2010 / NDP 4.0中的C#4.0编译器版本修复了这个问题,但现在没有计划在Orcas中修复它,不幸的是我没有解决这个问题。

我不想这么说但是当你可以解决这个问题时,你需要升级到NDP 4 csc.exe或VS2010。

我正在考虑在我的新msdn博客上发布关于此的条目。制作一个很好的轶事示例,说明重构如何破坏您的代码。

Ian Halliday

C#编译器SDE
微软

答案 1 :(得分:14)

嗯......对我来说看起来像编译器错误!它没有通过以下(ECMA 334v4):

  

24.4.3 Obsolete属性Obsolete属性用于标记   类型和应该类型的成员   不再使用。如果程序使用了   用...装饰的类型或成员   Obsolete属性,然后是   编制者应发出警告或   错误以提醒开发人员,   所以违规代码可以修复。   具体而言,编译器应发布   如果没有错误参数则发出警告   提供,或者如果错误参数是   提供并且值为false。该   编译器应发出编译时   错误参数是错误   指定并且值为true。

特别是,当标记为true时,它应该发出错误,但它不会。很好找!你可以在“连接”上报告它,或者如果你不想设置登录的痛苦,请告诉我,我会很乐意记录它(在这里引用你的帖子;不试图“窃取”任何东西)。 / p>

(更新)

缩减代码以重现:

using System;
using System.Collections.Generic;
static class Program {
    static void Main() {
        int count = Test.Count;
    }

    [Obsolete("Should error", true)]
    public static List<string> Test {
        get {throw new NotImplementedException();}
    }
}

请注意,mono 2.0使其正确,MS C#2.0编译器也是如此。只有MS C#3.0(.NET 3.5)编译器坏了。

答案 2 :(得分:4)

我同意Marc:它看起来像编译错误。有趣的是,gmcs(Mono C#编译器)做对了:

Test.cs(65,26): warning CS0219: The variable `list' is assigned but its value is never used
Test.cs(62,38): warning CS0612: `TestApp.BaseClass.Value' is obsolete
Test.cs(63,38): warning CS0612: `TestApp.BaseClass.ValueArray' is obsolete
Test.cs(64,38): warning CS0612: `TestApp.BaseClass.ValueList' is obsolete
Test.cs(65,36): warning CS0612: `TestApp.BaseClass.ValueList' is obsolete
Compilation succeeded - 5 warning(s)