我试图将类上的集合属性标记为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 ListValueList { 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
这是一个真正的错误.不幸的是,由于重构清理错过了这种情况.我为VS 2010/NDP 4.0中出现的C#4.0编译器版本修复了这个问题,但是现在没有计划在Orcas中修复它,不幸的是我无法解决这个问题.
我不想这么说但是当你可以解决这个问题时,你需要升级到NDP 4 csc.exe或VS2010.
我正在考虑在我的新msdn博客上发布关于此的条目.制作一个很好的轶事示例,说明重构如何破坏您的代码.
Ian Halliday
C#编译器SDE
Microsoft
嗯......对我来说看起来像编译器错误!它没有通过以下(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 ListTest { get {throw new NotImplementedException();} } }
请注意,mono 2.0使其正确,MS C#2.0编译器也是如此.只有MS C#3.0(.NET 3.5)编译器坏了.