Image 和 Bitmap 类没有实现自定义相等/哈希码逻辑的原因是什么?
从 MSDN 文档来看,GetHashCode() 和 Equals() 似乎都没有在 Bitmap 中被重写。它们也没有在 Image 中被覆盖。所以这两个类都使用它们的对象版本,只是比较引用。我不太相信,所以我决定启动 Reflector 来检查一下。看来 MSDN 在这件事上是正确的。
那么,是否有任何特殊原因导致 MS 人员不会实现“比较逻辑”,至少对于 Bitmap 类来说是这样?我发现它对于 Image 来说还可以接受,因为它是一个抽象类,但对于 Bitmap 类则不然。我可以看到在很多情况下计算哈希码可能是一项昂贵的操作,但如果它使用某种缓存就可以了。
当想要比较 2 个位图时,我是否必须在整个图片上运行来比较其每个像素?
谢谢
From MSDN documentation, it seems as both GetHashCode() and Equals() haven't been overriden in Bitmap. Neither have them been overriden in Image. So both classes are using the Object's version of them just compares references. I wasn't too convinced so I decided to fire up Reflector to check it out. It seems MSDN is correct in that matter.
So, is there any special reason why MS guys wouldn't implement "comparison logic", at least for the Bitmap class? I find it is kinda acceptable for Image, as it is an abstract class, but not so much for the Bitmap class. I can see in a lot of situations calculating the hash code can be an expensive operation, but it'd be alright if it used some kind of caching.
When wanting to compare 2 bitmaps, will I have to resort to having to run all over the picture comparing each one of its pixels?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
.net 框架中的相等语义已经得到了很好的标准化;如果以您期望的方式对位图的引用进行相等性测试,则似乎违反了最不意外的原则。
Equality semantics in the .net framework are pretty well standardized; it would seem to violate the principal of least surprise if references to bitmaps tested for equality in the way you expected.
当运行 MS 未实现的内置位图比较时,它需要比较每个像素。当然,MS 可能会进行原始内存比较(可能在不安全的块中),但如果您愿意,您也可以做同样的事情。无论如何,比较两个位图总是很昂贵的。而且您不能同时依赖哈希值,因为计算哈希值通常与比较一样昂贵……而且当哈希值匹配时,您将被迫依赖原始像素比较来验证相等性,因为哈希值只能证明不相等性。
我没有提供
Equals
和GetHashCode
在Bitmap
中无用的演示。然而,我已经提供了一个演示,表明它们通常会给用户带来令人惊讶的、意想不到的成本,并且在普通用例中不会是一个好的解决方案。向这样的类型添加额外的功能是昂贵的,而且我不相信它会有多大好处。而且往往会花费很多钱。这是您应该自己实现的事情,或者使用第三方库。When the built-in bitmap comparison that MS did not implement is run, it would need to resort to comparing each of the pixels. Sure, MS would probably do a raw memory comparison (perhaps in an unsafe block), but you can do the same thing if you want. Regardless, comparing two bitmaps will always be expensive. And you cannot rely on hashes both because calculating a hash is generally going to be as expensive as a comparison...and you'll be forced to rely on a raw pixel comparison to verify equality when the hashes match, since hashes only prove inequality.
I have not provided a demonstration that
Equals
andGetHashCode
are useless in aBitmap
. However, I have provided a demonstration that they are often going to offer surprising, unexpected costs to users and will not be a good solution in ordinary use cases. Adding extra functionality to a type like this is expensive, and I'm not convinced it would have much benefit. And it would often cost a lot. This is the kind of thing you should implement yourself, or use a 3rd party library.图像和位图通常是可变引用类型。可变引用类型永远不应该覆盖
Equals(Object)
,因为Equals(Object)
不应该报告两个对象是否碰巧具有相同的值调用时的状态,而是两个对象是否始终且永远相等。即使两个可变对象碰巧在某一时刻具有相同的状态,这也绝不意味着它们将始终如此。Images and bitmaps are generally mutable reference types. Mutable reference types should never override
Equals(Object)
, sinceEquals(Object)
is not supposed to report whether two objects happen to have the same state at the time it's called, but rather whether two objects will always and forevermore be equivalent. Even if two mutable objects happen to have the same state at one moment in time, that would in no way imply that they will always do so.让我们把这个问题反过来看;他们实施这样的事情有什么特殊原因吗?
一方面,计算哈希值将非常非常昂贵,这使得它对于哈希表等几乎毫无用处。试着想象一下在一大堆 1920x1200 位图上执行此操作;即使对每个位图执行一次一次都会使程序变得缓慢。我预计十分之九的情况是,当有人必须比较两个位图时,他们想要引用相等,而不是逐像素值相等。
你在问题中提到的不是惰性评估,而是缓存。缓存是一项需要实现的重要功能,每个功能都从 负 100 分。
考虑到所有这些,我对此的回答是,这些方法不会被重写,因为相对于实现和维护此类功能的成本,被重写的版本对很多人来说并不是特别有用。如果您确实想要逐像素比较(或校验和,或类似的东西),那么您始终可以自己在 10 行左右的时间内实现它们。
Let's flip that question around; is there any special reason why they would implement such a thing?
For one thing, it would be very, very expensive to compute the hash, making it all but useless for hash tables and the like. Just try to imagine doing this on a whole slew of 1920x1200 bitmaps; doing it even one time for each bitmap would slow the program to a crawl. I would expect that 9 times out of 10, when somebody has to compare two bitmaps, they want reference equality, not pixel-by-pixel value equality.
And what you refer to in your question isn't lazy evaluation, it's caching. Caching is a non-trivial feature to implement, and every feature starts at minus 100 points.
With all that in mind, my answer to this would be that the methods aren't overridden because the overridden versions wouldn't be particularly useful to many people, relative to the cost of implementing and maintaining such a feature. If you really want pixel-by-pixel comparisons (or checksums, or similar things), then you can always implement them yourself in 10 lines or so.