Header menu logo G-Research F# Analyzers

ImmutableCollectionEquality Analyzer

Problem

ImmutableDictionary and ImmutableHashSet do not have an implementation for structural equality.
Calling .Equals on them or using = can be misleading as the reference equality will be checked.
See source code for Immutable collections

open System.Collections.Immutable

let a = ImmutableDictionary.Create<int, string>().Add(1, "Dave")
let b = ImmutableDictionary.Create<int, string>().Add(1, "Dave")

// Analyzer will trigger
a = b

Fix

It is more likely that fellow developers understand your intent if you use ReferenceEquals in such cases.

open System.Collections.Immutable

let a = ImmutableDictionary.Create<int, string>().Add(1, "Dave")
let b = ImmutableDictionary.Create<int, string>().Add(1, "Dave")

// This makes it more clear that only reference equality is checked.
Object.ReferenceEquals(a, b)
namespace System
namespace System.Collections
namespace System.Collections.Immutable
val a: ImmutableDictionary<int,string>
Multiple items
type ImmutableDictionary = static member Contains<'TKey,'TValue> : map: IImmutableDictionary<'TKey,'TValue> * key: 'TKey * value: 'TValue -> bool static member Create<'TKey,'TValue> : unit -> ImmutableDictionary<'TKey,'TValue> + 2 overloads static member CreateBuilder<'TKey,'TValue> : unit -> Builder<'TKey,'TValue> + 2 overloads static member CreateRange<'TKey,'TValue> : items: IEnumerable<KeyValuePair<'TKey,'TValue>> -> ImmutableDictionary<'TKey,'TValue> + 2 overloads static member GetValueOrDefault<'TKey,'TValue> : dictionary: IImmutableDictionary<'TKey,'TValue> * key: 'TKey -> 'TValue + 1 overload static member ToImmutableDictionary<'TKey,'TValue> : source: IEnumerable<KeyValuePair<'TKey,'TValue>> -> ImmutableDictionary<'TKey,'TValue> + 8 overloads
<summary>Provides a set of initialization methods for instances of the <see cref="T:System.Collections.Immutable.ImmutableDictionary`2" /> class. NuGet package: System.Collections.Immutable (about immutable collections and how to install)</summary>

--------------------
type ImmutableDictionary<'TKey,'TValue> = interface ICollection<KeyValuePair<'TKey,'TValue>> interface IEnumerable<KeyValuePair<'TKey,'TValue>> interface IEnumerable interface IDictionary<'TKey,'TValue> interface IReadOnlyCollection<KeyValuePair<'TKey,'TValue>> interface IReadOnlyDictionary<'TKey,'TValue> interface ICollection interface IDictionary interface IImmutableDictionary<'TKey,'TValue> member Add: key: 'TKey * value: 'TValue -> ImmutableDictionary<'TKey,'TValue> ...
<summary>Represents an immutable, unordered collection of keys and values. NuGet package: System.Collections.Immutable (about immutable collections and how to install)</summary>
<typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
<typeparam name="TValue">The type of the values in the dictionary.</typeparam>
ImmutableDictionary.Create<'TKey,'TValue>() : ImmutableDictionary<'TKey,'TValue>
ImmutableDictionary.Create<'TKey,'TValue>(keyComparer: System.Collections.Generic.IEqualityComparer<'TKey>) : ImmutableDictionary<'TKey,'TValue>
ImmutableDictionary.Create<'TKey,'TValue>(keyComparer: System.Collections.Generic.IEqualityComparer<'TKey>, valueComparer: System.Collections.Generic.IEqualityComparer<'TValue>) : ImmutableDictionary<'TKey,'TValue>
Multiple items
val int: value: 'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
Multiple items
val string: value: 'T -> string

--------------------
type string = System.String
val b: ImmutableDictionary<int,string>

Type something to start searching.