-
Notifications
You must be signed in to change notification settings - Fork 213
extend or implements from a generic type #3552
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
How are you going to use the B class after that? |
I am not sure what you are trying to achieve. What would be the use-case of this esoteric approach? What problem are you trying to solve with this? I don't even know if this is possible, as we would have to solve a lot of problems, like, how would we dynamically implement the interface we are instantiating? There's probably a better way to solve what you are trying to solve, whatever problem it is... |
That's very unlikely to happen. The problem is that
Basically, it's impossible to do anything safely or soundly, which means that this particular design is unsuited for the Dart language. A "class" which doesn't know its concrete superclass, but may have an idea about its interface, is what a |
What I think he's really trying to say is that he'd like to be able to guarantee that type T is a supertype of A. Something like: class A<T super A> {} Related to #1674. |
The actual requirement is more for
than
Or more precisely
where A is an abstract interface class. eg
The idea is that A is a proxy for an abstract interface that we can use to specify the relationships between interfaces At the moment I have to do:
|
Now, I completely agree that using noSuchMethod in this way means that we are bypassing the static checking that would otherwise be a very good thing. If there were some checkable way of delegating an implementation to an interface, then that would be better. |
Also, I can hear the chorus of replies "that's what all the meta-programming stuff is for". But waiting for that seems overkill for something that is almost already there. |
And of course we can ( from the original example ) do:
In which case, you can re-interpret my request as the ability to overload the '.' operator :). |
I was expecting something like a proxy, where the type to be proxied is determined dynamically by the type argument. I'll say that The biggest issue is still that the interface of the type depends on the type parameter. It is not determined until It's not possible to implement such a class with anything but class ProxyWithDelay<T> implements T {
final Duration milliseconds;
final Object? Function(Invocation) _handler;
ProxyWithDelay(this._handler, this.milliseconds);
Object? noSuchMethod(Invocation invocation) {
sleep(milliseconds);
return _handler(invocation);
}
} That looks weird, but it is what it is. Then it's used as dynamic proxy<T>(Object? Function(Invocation) handler) =>
ProxyWithDelay<T>(handler, Duration(milliseconds: 25));
// ...
dynamic p = proxy<DateTime>(...);
DateTime date = p;
ProxyWithDelay proxy = p;
int ms = date.milliseconds;
Duration delay = proxy.milliseconds; That code satisfies all the stated requirements of the classes involved, and the So the proxy class is not allowed to declare any members. It's not allowed to inherit any members. So we're back to a class declaration with no superclass, no other implemented types, and no members. So imagine instead that we had a function: external T dynamicProxy<T>(dynamic Function(Invocation) invocationHandler); which returns a proxy object implementing Every member will have to be implemented using the invocation handler (which is a glorified user-provided That sound much more likely as a way to introduce a proxy than |
Having read this through quite a few times, I think I get it. The reason that
is ok is that the interface is known at this point, and so Dart can do the checking it needs to do to see if this is a well-formed class. As you might have guessed, I come from a C++ background where
is fine ( although we lack the introspection capabilities to do the forwarding to the interface automatically ). But I assume this is because the template expansion is done during run time in C++ ? Will the meta-programming stuff allow us to create a macro that creates MyProxy ? |
It works in C++ because template instantiation happens before type checking. A template in C++ really is a template: it's a piece of unprocessed syntax that doesn't become real compilable C++ code until after template arguments are applied. This makes templates very powerful, but it also leads to C++'s famously inscrutable compile errors. Dart, like most newer languages with generics, has taken a different approach where generic code can be type checked before instantiation using bounds, traits, or some other constraint mechanism. |
I'd like to be able to do something like this:
class A<T> extends T { ... }
or
class B<T> implements T { ... }
The text was updated successfully, but these errors were encountered: