.net 为什么这两个类型相同的F#类对象不相等?
有人能向我解释为什么这两个对象不相等,以及处理这些问题的解决方案是什么.net 为什么这两个类型相同的F#类对象不相等?,.net,.net-core,f#,.net,.net Core,F#,有人能向我解释为什么这两个对象不相等,以及处理这些问题的解决方案是什么 [<AllowNullLiteralAttribute>] type Duration (id, startDate, endDate) = member val DbId : string = id with get,set member val StartDate : Nullable<DateTime> = startDate with get,set memb
[<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
[]
类型持续时间(id、开始日期、结束日期)=
成员val DbId:string=id,带get,set
成员val StartDate:Nullable=StartDate和get,set
成员val EndDate:Nullable=EndDate和get,set
新的()=
持续时间(null,System.Nullable(),System.Nullable())
[]
类型ProductMedium(mediumType、fileLink、duration)=
成员val MediumType:string=MediumType和get,set
成员val FileLink:string=FileLink和get,set
成员val持续时间:持续时间=获取、设置的持续时间
新的()=
ProductMedium(空、空、空)
让medium1=newproductmedium(“Type1”,null,null)
让medium2=newproductmedium(“Type1”,null,null)
medium1=medium2//返回false
这就是.NET中相等的工作原理:默认情况下,除非您自己实现比较方法,否则相等是“通过引用”的,即每个对象只与自身相等,而与其他对象不相等
对于许多标准库类型,例如字符串,实际上实现了比较方法。这就是为什么相等的字符串是相等的,即使它们不是同一个对象。但是对于您自己滚动的类型,您必须实现您认为合适的比较方法
对于您在这里试图做的事情,您想要的方法是。这是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
现在,比较将按照您期望的方式进行。但您也会收到一条警告,要求您也实施。这是因为.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#记录在默认情况下具有“结构相等”(即,当所有字段相等时,两个记录相等),由编译器为您实现,但它们还提供其他好处,如语法更短、默认不可变、函数更新语法、模式匹配、类型推断等。强烈推荐