Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding copyWith #65

Open
umasagashi opened this issue Oct 1, 2022 · 2 comments
Open

Allow overriding copyWith #65

umasagashi opened this issue Oct 1, 2022 · 2 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@umasagashi
Copy link

If copyWith of the base class that is overridden by the subclass is called, copyWith of the subclass should be called.
However, since extension will not be overridden in dart, copyWith of the base class will be called.

@CopyWith()
class Base {
  int x;
  Base({required this.x});
  Base copyWith2({int? x}) => Base(x: x ?? this.x);
}

@CopyWith()
class Extended extends Base {
  int y;
  Extended({required super.x, required this.y});
  @override
  Extended copyWith2({int? x, int? y}) => Extended(x: x ?? this.x, y: y ?? this.y);
}

void main() {
  final Base base = Extended(x: 1, y: 2);
  print(base.copyWith()); // flutter: Instance of 'Base'  <-- should be Extended
  print(base.copyWith2()); // flutter: Instance of 'Extended'
}

Also, in such a design, Base may be abstract, in which case copy_with_extension generates code that cannot be compiled.


I have researched about this and found this solution:

  1. Delete _$BaseCWProxyImpl and $BaseCopyWith. (which are implementations for an abstract class).
  2. Change _$ExtendedCWProxy extends _$BaseCWProxy.
  3. Change copyWith in $ExtendedCopyWith private. (Optional)

Then, this can be achived as below:

@CopyWith()
abstract class Base {
  int x;
  Base({required this.x});
  _$BaseCWProxy get copyWith;
}

@CopyWith()
class Extended extends Base {
  int y;
  Extended({required super.x, required this.y});
  @override
  _$ExtendedCWProxy get copyWith => _copyWith;
}

void main() {
  final Base base = Extended(x: 1, y: 2);
  print(base.copyWith()); // flutter: Instance of 'Extended'
}

Could you add options for this? Or is there any better way to do this?

@rasitayaz
Copy link
Contributor

i was just looking for this exact feature, would be great 🙏

@numen31337 numen31337 added bug Something isn't working enhancement New feature or request labels Feb 25, 2023
@MohamadGreatWarrior
Copy link

A workaround I found is to define factory constructor in the base class.

factory BaseClass.copyWith(
    BaseClass oldInstance, {
    ...args
  }) {
    if (oldInstance is ExtendedClass) {
      return ExtendedClass(
        ...args
      );
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants