为什么在调用 C# 集合属性的属性时,它们没有被标记为过时?
我尝试将类上的集合属性标记为“已过时”,以查找所有出现的情况,并在警告列表中保留要修复的不断缩小的内容列表,因为我们需要用其他内容替换此集合属性。
编辑:我已通过 Microsoft Connect 提交此内容,问题#417159。
编辑 16.11.2010:已验证此功能现在可以在 C# 4.0 编译器中运行,无论是针对 .NET 3.5 还是 4.0 进行编译。 我在发布的代码中收到 4 条警告,其中一条带有注释“不好?”。
然而,令我惊讶的是,该列表仅包含少数出现次数,比我知道的要少得多,并且抽查告诉我,由于某种原因,该属性的使用并不总是被编译器在警告列表中标记为过时。
下面是一个示例程序,准备在 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
}
}
}
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
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个真正的错误。 不幸的是,由于重构清理错过了这个案例。 我为 VS 2010/NDP 4.0 中即将发布的 C# 4.0 编译器版本修复了此问题,但现在没有计划在 Orcas 中修复此问题,不幸的是,据我所知,没有解决此问题的方法。
我不想这么说,但您需要升级到 NDP 4 csc.exe 或 VS2010(当它们可用时才能解决此问题)。
我正在考虑在我的新 msdn 博客上发布关于此的条目。 这是一个很好的轶事例子,说明重构如何破坏您的代码。
Ian Halliday
C# 编译器 SDE
微软
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
嗯...对我来说看起来像是一个编译器错误! 它无法满足以下条件 (ECMA 334v4):
特别是,当标记为 true 时,它应该发出错误,但事实并非如此。 好发现! 您可以在“连接”上报告它,或者如果您不想设置登录的痛苦,请告诉我,我会很乐意记录它(在这里引用您的帖子;不试图“窃取”任何东西)。
(更新)
减少重现的代码:
请注意,mono 2.0 是正确的,MS C# 2.0 编译器也是如此。 只有 MS C# 3.0 (.NET 3.5) 编译器被破坏。
Hmm... looks like a compiler bug to me! It fails the following (ECMA 334v4):
In particular, when marked true it should issue an error, and it doesn't. Good find! You could report it on "connect", or if you don't want the pain of setting up a login, let me know and I'll happily log it (referencing your post here; no attempt to "steal" anything).
(update)
Reduced code to reproduce:
Note that mono 2.0 gets it right, as does the MS C# 2.0 compiler. It is only the MS C# 3.0 (.NET 3.5) compiler that is broken.
我同意马克的观点:它看起来像是一个编译器错误。 有趣的是,gmcs(Mono C# 编译器)的说法是正确的:
I agree with Marc: it looks like a compiler bug. Interestingly, gmcs (the Mono C# compiler) gets it right: