当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《为什么C#collection-properties在调用它们的属性时没有被标记为过时?》经验,为你挑选了2个好方法。

我试图将类上的集合属性标记为Obsolete以查找所有出现并在我的警告列表中保留缩小的事项列表,因为我们需要用其他东西替换此集合属性.


编辑:我已通过Microsoft Connect提交此问题,问题#417159.

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


然而,令我惊讶的是,该列表只包含了一些内容,远远少于我所知道的,并且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 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 ValueList
        {
            get
            {
                return new List(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 list = bc.ValueList;            // #4 - OK
        }
    }
}

Ian Halliday.. 18

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

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

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

Ian Halliday

C#编译器SDE
Microsoft



1> Ian Halliday..:

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

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

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

Ian Halliday

C#编译器SDE
Microsoft



2> Marc Gravell..:

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

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

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

(更新)

减少重现的代码:

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

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

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

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有