I have a few similar functions in my project that works the same but have different return types. Is it possible for me to factorise them into 1 function to reduce code reducndancy?
Below is my code sample:
class A {
final String code;
final String name;
}
class B {
final String name;
final String leaveDate;
}
List<A> testFunc(String value, List<A> list) {
List<A> result = [];
for (var E in list) {
if (E.name!.toLowerCase().contains(value)) {
result.add(E);
}
}
return result;
}
List<B> testFun1(String value, List<B> list) {
List<B> result = [];
for (var E in list) {
if (E.name!.toLowerCase().contains(value)) {
result.add(E);
}
}
return result;
}
I have tired to pass out List<dynamic>
but it does seem working on my project.
Some options:
Make A
and B
both derive from a common base interface that provides a name
getter:
abstract interface class HasName {
String get name;
}
class A implements HasName {
final String code;
@override
final String name;
A({required this.code, required this.name});
}
class B implements HasName {
@override
final String name;
final String leaveDate;
B({required this.name, required this.leaveDate});
}
List<T> testFunc<T extends HasName>(String value, List<T> list) {
List<T> result = [];
for (var e in list) {
if (e.name.toLowerCase().contains(value)) {
result.add(e);
}
}
return result;
}
Alternatively make your generic function use callback for the getter:
List<T> testFunc<T>(String value, List<T> list, String Function(T) getName) {
List<T> result = [];
for (var e in list) {
if (getName(e).toLowerCase().contains(value)) {
result.add(e);
}
}
return result;
}
and then call it with something like testFunc('foo', listOfA, (a) => a.name)
.
If you want to give up static type safety and to use duck-typing instead, you can treat List
elements as dynamic
:
List<T> testFunc<T>(String value, List<T> list) {
List<T> result = [];
for (var e in list) {
if ((e as dynamic).name.toLowerCase().contains(value)) {
result.add(e);
}
}
return result;
}