Allow factory constructors to specify a return type #4153
Labels
brevity
A feature whose purpose is to enable concise syntax, typically expressible already in a longer form
enhanced-const
Requests or proposals about enhanced constant expressions
feature
Proposed language feature that solves one or more problems
Constructors generally don't specify a return type because they will return an instance of the enclosing class, so it's redundant.
However, this is not the whole truth when it comes to factory constructors. They may in general return an instance of an arbitrary subtype of the enclosing class. For example:
This is a typical use case, and the point is that the class
A
provides a public (possibly widely used) interface, and the actual implementation is provided by one or more subtypes like_AImpl
. In general, client code does not need (or want!) to depend on those subtypes, so they are removed from public access (and may even be private) and client code only gets to use them because they can call some redirecting factories likeA
.However, we can also have situations where the subclasses are public in nature, and we'd like to combine the ability to call constructors declared by the supertype, and still have access to the interface of each of the subtypes. In this case we could allow the redirecting factory constructor to declare a return type (which must be a subtype of the type of the class, including any type arguments as declared):
It may seem contradictory to wish to have the interface of
B<T>
in an expression that looks likeA<T>()
for someT
. However, the discussion in #357 has repeatedly brought up a situation where it may be convenient, namely the case where an expression likeEdgeInsetsGeometry.all(16.0)
is abbreviated to.all(16.0)
based on havingEdgeInsetsGeometry
as the context type.The idea is that we provide constructors of subtypes like
EdgeInsets
andEdgeInsetsDirectional
as constructors ofEdgeInsetsGeometry
. That's nothing new, but we do want to have access to members of those subclasses, and this will only work if we can declare the return type:A couple of brevity features (#4135 and #4144) would allow us get exactly the same behavior with less noise:
We might even say that if a redirecting factory constructor declares a return type then it will serve as the default class name in the redirection:
Note that
.
is punctuation, which means that the parser will have no difficulty parsing the declaration with no space before the.
, in case that's the preferred style (as inconst factory EdgeInsets.all = .all;
).The point is that we can now tailor the static namespace of
EdgeInsetsGeometry
such that it offers constructors of various subtypes of that class (such that we can use the.identifier(...)
syntax to invoke it when the context type isEdgeInsetsGeometry
). It preserves the ability to use the enhanced interface of the given subtype in the instance creation expression itself (as in.all(10).copyWith(right: 15)
), and it preserves the ability to be constant.Finally, non-redirecting factory constructors could also allow for a declared return type:
This could be used with the
.identifier
syntax as well, for similar reasons.The text was updated successfully, but these errors were encountered: