Freezed: Override/overloading an operator like == from the abstract class

Created on 4 Oct 2020  路  9Comments  路  Source: rrousselGit/freezed

Is your feature request related to a problem? Please describe.
I need to have a way to customize the overloading like operator == in the class

Describe the solution you'd like
I have a class with multiple needed properties but I only need to compare some of the properties in that list to determine if the two instances are equal.

Describe alternatives you've considered
I need to make a mental note to change the generated code to fit my need, this is not recommended and not an elegant way to do it.

Additional context
Add any other context or screenshots about the feature request here.
I have this abstract class

@freezed
abstract class BleDevice with _$BleDevice {
  const BleDevice._();

  factory BleDevice(
      {String name,
      String id,
      int rssi,
      Peripheral peripheral,
      PeripheralConnectionState peripheralConnectionState}) = _BleDevice;
}

The generated code compare all of the values to determine if it is equal

  @override
  bool operator ==(dynamic other) {
    return identical(this, other) ||
        (other is _BleDevice &&
            (identical(other.name, name) ||
                const DeepCollectionEquality().equals(other.name, name)) &&
            (identical(other.id, id) ||
                const DeepCollectionEquality().equals(other.id, id)) &&
            (identical(other.rssi, rssi) ||
                const DeepCollectionEquality().equals(other.rssi, rssi)) &&
            (identical(other.peripheral, peripheral) ||
                const DeepCollectionEquality()
                    .equals(other.peripheral, peripheral)) &&
            (identical(other.peripheralConnectionState,
                    peripheralConnectionState) ||
                const DeepCollectionEquality().equals(
                    other.peripheralConnectionState,
                    peripheralConnectionState)));
  }

I only need to compare the values below

  @override
  bool operator ==(other) =>
      other is BleDevice &&
      this.name != null &&
      other.name != null &&
      compareAsciiLowerCase(this.name, other.name) == 0 &&
      this.id == other.id;

I hope there is a way to do this already, if so, please point me to the right direction.

Thanks!

enhancement

Most helpful comment

That's not a bug

It's not that this isn't possible to update Freezed to support that but rather that this is a _really_ bad practice to have ==/hashcode ignore some properties, so I don't see any reason to promote such usage.

A better solution is to convert your class into a smaller class with only the properties you need:

@freezed
abstract class BigObject with _$BigObject {
  BigObect._();
  factory BigObject({int a, int b, int c, int d}) = _BigObject;

  OnlyAB asOnlyAB() => OnlyAB(a: a, b: b);
}

@freezed
abstract class OnlyAB with _$OnlyAB {
  factory OnlyAB({int a, int b}) = _OnlyAB;
}

@rrousselGit you are right. But, sometimes you got a pretty large class, result of an API call with multiple properties and you want the objects to be compared only by some of them.

Moreover, you can't always tell your boss to make smaller (but multiple classes) just to have nice comparison facility (And you know how nightmare is to write classes without freezed).

At last, it's your choice what to do.

All 9 comments

I'm also running into issues with properties that should not be compared. Would appreciate a fix for this.

I have models that reference each other and using Freezed causes infinite recursion. I don't recall this happening in earlier versions.

One of my pointers is a subclass of Set and DeepCollectionEquality() compares the elements directly, ignoring the class' specific equals/hashCode implementation.

  int hash(Object? o) {
    if (o is Set) return SetEquality(this).hash(o);

Any workarounds in the meantime?

@rrousselGit would it be possible to honor the class equals/hashCode or otherwise exclude certain properties?

I already opened such issue before: #237
According to Remi, this isn't possible

@RaviKavaiya thanks!

It is definitely possible to fix.

He probably has other reasons.

@alextran1502 Would you mind changing the label enhancement to bug?

That's not a bug

It's not that this isn't possible to update Freezed to support that but rather that this is a really bad practice to have ==/hashcode ignore some properties, so I don't see any reason to promote such usage.

A better solution is to convert your class into a smaller class with only the properties you need:

@freezed
abstract class BigObject with _$BigObject {
  BigObect._();
  factory BigObject({int a, int b, int c, int d}) = _BigObject;

  OnlyAB asOnlyAB() => OnlyAB(a: a, b: b);
}

@freezed
abstract class OnlyAB with _$OnlyAB {
  factory OnlyAB({int a, int b}) = _OnlyAB;
}

@rrousselGit I do think it's a bug to ignore equals/hashcode of a class, as Freezed does at the moment.

Regarding ignoring properties, context is important. For example if I have transient properties in my object, I think it's bad practice to include them in equals/hashcode.

Some flexibility in this aspect would be much appreciated, because Freezed is otherwise a great tool.

That's not a bug

It's not that this isn't possible to update Freezed to support that but rather that this is a _really_ bad practice to have ==/hashcode ignore some properties, so I don't see any reason to promote such usage.

A better solution is to convert your class into a smaller class with only the properties you need:

@freezed
abstract class BigObject with _$BigObject {
  BigObect._();
  factory BigObject({int a, int b, int c, int d}) = _BigObject;

  OnlyAB asOnlyAB() => OnlyAB(a: a, b: b);
}

@freezed
abstract class OnlyAB with _$OnlyAB {
  factory OnlyAB({int a, int b}) = _OnlyAB;
}

@rrousselGit you are right. But, sometimes you got a pretty large class, result of an API call with multiple properties and you want the objects to be compared only by some of them.

Moreover, you can't always tell your boss to make smaller (but multiple classes) just to have nice comparison facility (And you know how nightmare is to write classes without freezed).

At last, it's your choice what to do.

I don't think we can agree here.
I do not want to spend time working on something I do not want to promote. But you're free to make a pull-request.

Was this page helpful?
0 / 5 - 0 ratings