Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 为什么这两个类型相同的F#类对象不相等?_.net_.net Core_F# - Fatal编程技术网

.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#记录在默认情况下具有“结构相等”(即,当所有字段相等时,两个记录相等),由编译器为您实现,但它们还提供其他好处,如语法更短、默认不可变、函数更新语法、模式匹配、类型推断等。强烈推荐