diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c2287f2..d09e197 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,6 @@ +### 4.0.3+36c543f (Released 2024-10-16) +- fix GetHashCode member failing for null property values + ### 4.0.2 (Released 2024-10-15) - Undo `DynObj.combine` working with `#DynamicObj` as input - this caused issues with ncombining nested DOs of types that inherited from DynamicObj. The type signature has been fixed to `DynamicObj` (without the flexible `#`) diff --git a/src/DynamicObj/HashCodes.fs b/src/DynamicObj/HashCodes.fs index 96bd4b4..9ff93d3 100644 --- a/src/DynamicObj/HashCodes.fs +++ b/src/DynamicObj/HashCodes.fs @@ -15,7 +15,10 @@ let hashDateTime (dt : System.DateTime) : int = let hash obj = - obj.GetHashCode() + if obj = null then + 0 + else + obj.GetHashCode() let boxHashOption (a: 'a option) : obj = if a.IsSome then a.Value.GetHashCode() else (0).GetHashCode() diff --git a/tests/DynamicObject.Tests/DynamicObjs.fs b/tests/DynamicObject.Tests/DynamicObjs.fs index 7dc02a1..168f384 100644 --- a/tests/DynamicObject.Tests/DynamicObjs.fs +++ b/tests/DynamicObject.Tests/DynamicObjs.fs @@ -535,6 +535,21 @@ let tests_GetHashCode = testList "GetHashCode" [ b2.SetProperty("c", 2) a2.SetProperty("b", b2) Expect.equal (a.GetHashCode()) (a2.GetHashCode()) "Values should be equal" + + testCase "null Value same key" <| fun _ -> + let a = DynamicObj() + a.SetProperty("b", null) + let b = DynamicObj() + b.SetProperty("b", null) + Expect.equal (a.GetHashCode()) (b.GetHashCode()) "Values should be equal" + + testCase "null Value different key" <| fun _ -> + let a = DynamicObj() + a.SetProperty("b", null) + let b = DynamicObj() + a.SetProperty("c", null) + Expect.notEqual (a.GetHashCode()) (b.GetHashCode()) "Values should not be equal" + ] let main = testList "DynamicObj (Class)" [ diff --git a/tests/DynamicObject.Tests/Inheritance.fs b/tests/DynamicObject.Tests/Inheritance.fs index 7689c1d..e497578 100644 --- a/tests/DynamicObject.Tests/Inheritance.fs +++ b/tests/DynamicObject.Tests/Inheritance.fs @@ -68,6 +68,13 @@ let tests_remove = testList "Remove" [ Expect.equal p.FirstName null "Static property should " + testCase "Remove Static HashCodeDoesNotFail" <| fun _ -> + let p = Person("123","John") + + p.RemoveProperty("FirstName") |> ignore + + p.GetHashCode() |> ignore + testCase "Remove Static Immutable" <| fun _ -> let p = Person("123","John") let f = fun () -> p.RemoveProperty("Id") |> ignore