当前位置: 首页 > 编程语言 > C#

C#编译器应该警告但不是?分享

时间:2023-04-10 19:29:40 C#

C#编译器应该警告但没有警告?我团队中有人试图修复空catch子句中的“未使用变量”警告。try{...}catch(Exceptionex){}->发出关于ex未被使用的警告。到目前为止,一切都很好。修复是这样的:tr??y{...}catch(Exceptionex){strings=ex.Message;}看到这个,我想“太好了,所以现在编译器会抱怨没有被使用”。但事实并非如此!此代码没有警告,我不明白为什么。有任何想法吗?附言。我知道让异常沉默的包罗万象的条款是一件坏事,但那是另一个话题。我也知道通过这样做可以更好地抑制初始警告,这也是题外话。try{...}catch(Exception){}或try{...}catch{}在这种情况下,编译器检测到s已写入但未读取,并故意抑制警告。原因是因为C#是一种垃圾收集语言,信不信由你。你怎么认为?那么,考虑以下几点。您有一个程序调用返回字符串的方法DoIt()。您没有DoIt()的源代码,但您想在调试器中检查它的返回值是什么。现在,在您的特定情况下,您使用DoIt()作为其副作用,而不是其返回值。所以你说DoIt();//丢弃返回值现在你正在调试你的程序,然后你去查看DoIt()的返回值并且它不存在,因为当调试器在调用DoIt()后中断时,垃圾收集编译器可能已经清除未使用的字符串。事实上,托管调试器没有“查看前一个方法调用返回的内容”的功能。非托管C++调试器具有该功能,因为它可以查看EAX寄存器,其中丢弃的返回值仍然存在,但在托管代码中,无法保证返回值在丢弃后仍然存在。现在,有人可能会争辩说这是一个有用的特性,并且调试器团队应该添加一个特性,如果在方法执行后立即出现调试器断点,则可以使返回值保持活动状态。那将是一个不错的功能,但我不是要求它的人;去调试组问问。可怜的C#开发人员做什么?创建局部变量,将结果存储在局部变量中,并在调试器中检查局部变量。调试器确保不会主动收集本地垃圾。所以你这样做,然后编译器会给你一个警告,你有一个只写而从不读的本地,因为读的东西不是程序的一部分,它是开发人员坐在那里看着调试器。这是一个非常烦人的用户体验!因此,我们检测到将非常量值分配给从未读取的局部变量或字段的情况,并抑制警告。如果你改变你的代码,那么它就是strings="hello";然后你会开始收到编译器的警告,这不可能是解决调试器限制的方法,因为它的值就在那里,开发人员可以在没有调试器的情况下读取它。这解释了一个。我们禁止在许多其他情况下从未读取过的变量警告;当我们报告警告时,以及当我们不花大量时间编写时,所有编译器策略的详细描述,所以我想我会离开它。变量s用于保存对ex.Message的引用。如果你只有字符串s;你会得到一个警告。我认为回答这个问题的人需要对编译器的工作原理有深刻的理解。然而,像FxCop这样的东西可能会捕捉到这一点。属性只是方法,没有什么可以阻止任何人将一些代码放入ex.Message属性中。因此,虽然您可能没有对s做任何事情,但调用ex.Message可能有价值......编译器的工作不是编译每个实例和极端情况,当变量可能会或可能不会被使用时。有些很容易发现,有些则更麻烦。谨慎是明智的(尤其是当警告可以设置为错误时——想??象一下软件是否因为编译器认为你没有使用某些东西而无法编译)。MicrosoftCompiler团队特别指出:“......我们对有兴趣发现代码中未使用元素的客户的指导是使用FxCop。它可以发现未使用的字段和更多有趣的代码数据。”–编译器平台开发总监Resharper主持的EdMaurer会发现,静态分析在今天可以做的事情上是有限的。(尽管Eric指出这不是因为它不知道这种情况。).NET4中的新代码契约极大地增强了静态检查,我相信总有一天您会在此类明显的错误上获得更多帮助。如果您尝试过CodeContracts,您就会知道对代码进行详尽的静态分析并不容易——每次编译后它可能会抖动几分钟。静态分析是否能够在编译时发现所有这样的问题?可能不是:参见http://en.wikipedia.org/wiki/Halting_problem。以上是C#学习教程:TheC#compilershouldwarnbutdoesn't?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: