-
Notifications
You must be signed in to change notification settings - Fork 214
[Feature] Allows calling factory methods of generic type #2039
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
Comments
So the problem is that you say /// Has a constructor called [namedConstructor].
class A {
A.namedConstructor();
}
/// Extends [A], but doesn't have a named constructor.
class B extends A { }
/// Calls the [namedConstructor] constructor on a subtype of [A].
A createA<T extends A>() => T.namedConstructor();
/// Tries to call [createA], but passes in [B] instead, which won't work.
void main() {
final B b = createA<B>();
} In other words, just because we know we have an instance of type There are three approaches to making this work:
A createA(A constructor(int)) => construct(42);
|
We should make the static interface inheritable, but we should not use class A {
A();
static int func0() => 0;
static A func1() => A();
/// Required to implement in subclass
static A.func2();
static A func3();
static int func4();
}
class B extends A {
B.func2();
static A func3() => A();
static int func4() => 4;
} I think we should use a new keyword like abstract class A {
static int func0() => 1;
static A func1() => A();
/// Required to implement in subclass
family.func2();
int family.func3();
/// Inheritable, overridable in a subclass
int family.func4() => 0;
}
/// VALID
abstract class B extends A {
}
/// INVALID
class C extends A {
/// Need to implement static methods [func2], [func3]
}
/// VALID
class D extends A {
final int x;
D(this.x);
factory D.func2() => D(1);
static int func3() => 4;
D family.func5() => D.func2();
}
/// VALID
class E extends D {
E(int x) : super(x);
static D func5() => D(2);
}
/// VALID
class F extends A {
F.func2();
static int func3() => 4;
static int func4() => 9;
} |
The word Dart doesn't treat static members as part of an interface at all. Instead, it's more like a namespace. Think of this class: class Namespace {
static void func1() { }
static void func2() { }
}
void main() {
Namespace.func1();
Namespace.func2();
} as equivalent to: // helpers.dart
void func1() { }
void func2() { } // main.dart
import "helpers.dart" as Namespace;
void main() {
Namespace.func1();
Namespace.func2();
} |
So, what about the solution using the class A {
A.func1();
}
typedef Func1<T> = T Function();
class B<T> {
T? createT() {
return T?.func1 is Func1<T> ? T.func1() : null;
}
} or class A {
A.func1();
}
typedef Func1Container<T> = {
T func1();
}
class B<T> {
T? createT() {
return T is Func1Container<T> ? T.func1() : null;
}
} |
As you can see, that's gonna be an error if
Same here, you're trying to see if abstract class Constructor<T> {
T new(); // "T.new" just means T's default constructor
}
class B<T> {
/// Returns a new [T] if [T] has a default constructor as in the [Constructor] class.
T? createT() => T is dynamic<Constructor<T>> ? T.new() : null;
} Alternatively, you can go the closure/callback route, by adding as a parameter a function that takes no parameters and returns a new final List<String> strings = ["Hello", "there", "new", "paragraph"];
final List<Text> texts = strings.map((String string) => Text(string)); // here's the closure So you can do the same in your case: typedef Constructor<T> = T Function();
T createT(Constructor<T> constructor) => constructor();
class Foo { }
class Bar {
Bar(int number, String text);
}
void main() {
final Foo = createT(Foo.new); // with "constructor-tearoffs" enabled, coming soon
final Bar = createT<Bar>(() => Bar(42, "Hello, World!"));
} Also see my comment at #356 (comment). |
@Levi-Lesches is this issue still open?? |
You can see the status of any issue at the top left, either a green "Open" near the title (as in this case), or a purple "Closed". |
I think this is a duplicate of #356. |
Ex:
The text was updated successfully, but these errors were encountered: