Chr*_*Rea 5 c# warnings fxcop suppress-warnings
我在C#项目中有一个复杂的类,我希望能够进行相等测试.这不是一个微不足道的阶级; 它包含各种标量属性以及对其他对象和集合的引用(例如IDictionary).为了它的价值,我的班级是密封的.
为了在我的系统中的其他地方启用性能优化(避免昂贵的网络往返的优化),我需要能够将这些对象的实例相互比较以实现相等 - 除了内置的引用相等 - 所以我重写了Object.Equals()实例方法.但是,现在我已经这样做了,Visual Studio 2008的代码分析又称FxCop,我默认启用它,它引发了以下警告:
警告:CA2218:Microsoft.Usage:由于'MySuperDuperClass'重新定义了Equals,它还应该重新定义GetHashCode.
我想我理解这个警告的基本原理: 如果我要将这些对象用作集合中的键,那么哈希码很重要.即看到这个问题.但是,我不打算将这些对象用作集合中的键.永远.
感觉有理由压制警告,我查找了MSDN文档中的代码CA2218以获取警告的全名,因此我可以将SuppressMessage属性应用于我的类,如下所示:
[SuppressMessage("Microsoft.Naming",
"CA2218:OverrideGetHashCodeOnOverridingEquals",
Justification="This class is not to be used as key in a hashtable.")]
Run Code Online (Sandbox Code Playgroud)
但是,在进一步阅读时,我注意到以下内容:
如何修复违规行为
要修复违反此规则的行为,请提供GetHashCode的实现.对于一对相同类型的对象,如果Equals的实现为该对返回true,则必须确保实现返回相同的值.
何时抑制警告
-----> 不要压制此规则的警告.[箭头和重点我的]
所以,我想知道:为什么我不应该按照我的计划来压制这个警告? 我的情况不是要求抑制吗?我不想为这个永远不会被调用的对象编写GetHashCode()的实现,因为我的对象永远不会成为集合中的键.如果我想要迂腐而不是抑制,那么用一个抛出NotImplementedException的实现覆盖GetHashCode()会更合理吗?
如果您定义的类型不会被用作容器中的键,那么这无关紧要.表示窗口控件,网页控件或数据库连接的类型不太可能用作集合中的键.在那些情况下,什么都不做.即使效率非常低,所有引用类型都将具有正确的哈希码.[...]在您创建的大多数类型中,最好的方法是完全避免GetHashCode()的存在.
...这就是我最初得到这个想法的地方,我不必总是关注GetHashCode().
Eri*_*ert 14
如果你是reallio-trulio absosmurfly 肯定你永远不会使用这个东西作为哈希表的关键,那么你的提议是合理的.覆盖GetHashCode; 让它抛出一个例外.
请注意,哈希表隐藏在不太可能的地方.大量LINQ序列运算符在内部使用哈希表实现来加快速度.通过拒绝GetHashCode的实现,您也拒绝在各种LINQ查询中使用您的类型.我喜欢构建使用memoization来提高速度的算法; memoizers通常使用哈希表.因此,您也拒绝记住将类型作为参数的方法调用的能力.
或者,如果你不想那么苛刻:覆盖GetHashCode; 使它总是返回零. 这符合GetHashCode的语义要求; 两个相等的对象总是具有相同的哈希码.如果它曾经被用作字典中的关键字,那么性能会很糟糕,但是当它出现时你可以处理它,你声称它永远不会.
所有这一切:来吧.您可能花了更多时间来输入问题,而不是正确实现它.去做就对了.
你不应该压制它.看看你的equals方法是如何实现的.我确信它比较了班上的一个或多个成员来确定平等.其中一个成员通常足以将一个对象与另一个对象区分开来,因此您可以GetHashCode通过返回来实现membername.GetHashCode();.
我的价值0.10美元?实现GetHashCode.
就像你说你永远不会需要它一样,你可能会改变主意,或者其他人可能对如何使用代码有其他想法.工作GetHashCode并不难,并保证将来不会出现任何问题.
一旦你忘记了,或者另一个不知道的开发人员使用了这个,有人会有一个痛苦的错误来追查.我建议只是正确实现GetHashCode,然后你就不用担心了.或者只是不要将Equals用于特殊的相等比较案例.