.net - 为什么这两个同类型的F#类对象不相等?
问题描述
有人可以向我解释为什么这两个对象不相等,处理这些问题的解决方案是什么?
[<AllowNullLiteralAttribute>]
type Duration (id, startDate, endDate) =
member val DbId : string = id with get,set
member val StartDate : Nullable<DateTime> = startDate with get,set
member val EndDate : Nullable<DateTime> = endDate with get,set
new () =
Duration(null, System.Nullable(), System.Nullable())
[<AllowNullLiteralAttribute>]
type ProductMedium (mediumType, fileLink, duration) =
member val MediumType : string = mediumType with get,set
member val FileLink : string = fileLink with get,set
member val Duration : Duration = duration with get,set
new () =
ProductMedium (null, null, null)
let medium1 = new ProductMedium("Type1", null, null)
let medium2 = new ProductMedium("Type1", null, null)
medium1 = medium2 // returns false
解决方案
这就是 .NET 中相等的工作原理:默认情况下,除非您自己实现比较方法,否则相等是“通过引用”的——也就是说,每个对象都只与自身相等,不与其他对象相等。
对于许多标准库类型,例如字符串,实际上已经实现了比较方法。这就是为什么相等的字符串是相等的,即使它们不是同一个对象。但是对于您自己滚动的类型,您必须实现您认为合适的比较方法。
对于您在这里尝试做的事情,您想要的方法是Equals
. 这是该System.Object
类型的一个虚方法,默认情况下它按照上述方式工作:每个对象都只与它自己相等。但是您可以为您的类型覆盖它:
type ProductMedium (mediumType, fileLink, duration) =
member val MediumType : string = mediumType with get,set
member val FileLink : string = fileLink with get,set
member val Duration : string = duration with get,set
override this.Equals(other) =
match other with
| :? ProductMedium as p ->
this.MediumType = p.MediumType && this.FileLink = p.FileLink && this.Duration = p.Duration
| _ ->
false
现在,比较将按照您期望的方式进行。但是您也会收到一条警告,要求您也实施GetHashCode
。这是因为 .NET 库中的许多标准容器(例如Dictionary
或Hashtable
)期望相等的对象也具有相同的哈希值,如果您的对象不这样做,则可能无法正常工作。我将把执行GetHashCode
留作练习。有关更多信息,请参阅文档。
但由于您使用的是 F#,实际上您有一个更好的选择:不要使用常规的 .NET 类,而是使用 F# 记录:
type ProductMedium = { MediumType : string; FileLink : string; Duration : string }
let medium1 = { MediumType = "Type1"; FileLink = null; Duration = null }
let medium2 = { MediumType = "Type2"; FileLink = null; Duration = null }
F# 记录默认具有“结构相等”(即当所有字段相等时,两条记录相等),由编译器为您实现,但它们还提供其他好处,例如更短的语法、默认不变性、功能更新语法、模式匹配、类型推断等。强烈推荐。
推荐阅读
- python - 尝试将附加参数传递给切换器库会导致“'NoneType' 对象不可调用”错误
- python - Cython 为数组分配内存而不使用 python
- java - 为什么我不能将数据从控制器传递到视图中的 img 标签
- python - Python 错误:“无类型”对象不支持项目分配
- python - Pandas DataFrame 自动解析日期
- oracle - 将 LONG 列转换为 VARCHAR2 到视图中
- ios - 当用户更改 UITextView 中的光标位置时,有没有办法阅读?
- ruby-on-rails - 有没有办法分解这个搜索代码?
- node.js - 前端(SPA)和后端解耦:JWT 认证 + 持久登录
- php - Magento 2.3 非常慢,有超过 100 条购物车线