Search code examples
flutterdartfreezedflutter-freezed

In Freezed generated classes, how to check if two objects are the same instance?


I'm using Freezed for dart immutable data modelling. This generator is overwriting == operator and the hasCode, which is fine for 99% of cases.

But I have a special case where comparing a long list take time and the List is managed internally. Because access from outside is not possible and I can guarantee that list is not updated, I can compare the instance itself instead of the content.

So the question is, how to check if two objects are the same instance?

If there is no way because overwriting the == operator and the hasCode method, is possible to disable the generation of both in this case, but still generate other code?

Note: There is a similar question here, but I want to continue using Freezed.


Solution

  • Take a look at the identical function. It checks whether two references are to the same object.

    identical(freezed_a, freezed_b);
    

    There are two special cases where identical returns true:

    1. For the same constant expressions;
    2. For the same value integers;

    It canonicalized them to the same object for performance reasons. From the docs:

    final a = new Object();
    final b = a;
    print(identical(a, Object())); // false, different objects.
    print(identical(a, b)); // true, same object
    print(identical(const Object(), const Object())); // true, const canonicalizes
    print(identical([1], [1])); // false
    print(identical(const [1], const [1])); // true
    print(identical(const [1], const [2])); // false
    print(identical(2, 1 + 1)); // true, integers canonicalizes
    

    So, in order to keep using the freezed class operator == just override it like the following example:

    @freezed
    class CustomEquals with _$CustomEquals {
      CustomEquals._();
      factory CustomEquals({String? name, int? id}) = _CustomEquals;
    
      @override
      bool operator ==(Object o) => o is CustomEquals && identical(o, this);
    
      @override
      int get hashCode => super.hashCode;
    }