Solution for https://github.com/dart-lang/language/issues/107, Related docs
This issue is for discussing the pros and cons of this particular proposal.
General discussion about the issue should go in #107 where everybody can see it.
I propose to add a new keyword – implicit that can be added to constructors and factories.
I think static conversion operators might work better (similar to C#). Example here: https://github.com/dart-lang/language/pull/105#issuecomment-442591897
class Uri {
...
// Add implicit conversions from String <-> Uri in both directions.
static operator String(Uri uri) => uri.ToString();
static operator Uri(String str) => Uri.parse(str);
}
The benefit is you can go in both directions. So the Uri class could define conversions to and from String. Makes it easier to support implicit conversions when you don't control both classes (e.g. similar to how extension methods let you add methods to a class you don't control).
The benefit is you can go in both directions.
Yup, that's a great analog.
I don't know why, but I'm drawn to a strict model here: "The only thing that can define implicit String -> Widget conversion is the Widget class".
It eliminate a lots of weirdness about which conversion is picked in a given context, etc.
...but certainly open to discuss!
Defining implicit conversion operations only on the source makes sense if you can use static extension methods to add them to any type. Ditto for only on the target type.
The difference is that on the source type, they can be treated as instance methods (like all other operators), but on the target type, they are constructors. Static extension methods would only work for instance methods.
Do we need an explicit way to invoke the implicit conversions?
Implicit conversions should happen only where there would otherwise be a compile-time error.
That measn that if I want to use the String to Uri conversion, I can't write "foo:bar" as Uri because the as does not perform an implicit cast. It's never a compile-time error.
So, do I have to write Uri x = "foo:bar"; instead, which means I can't do it in-line.
Consider the option of declaring normal instance members as cast members.
Any instance getter and any instance method which can be called with zero arguments can be marked as a cast. Assigning from a type to another incompatible type will check the type for accessible cast members which return a useful type (then try to pick the best one). You can always call the method or getter directly. Being a cast is automatically inherited by overriding members in subclasses.
You can also add cast extension methods.
Most helpful comment
I think static conversion operators might work better (similar to C#). Example here: https://github.com/dart-lang/language/pull/105#issuecomment-442591897
The benefit is you can go in both directions. So the Uri class could define conversions to and from String. Makes it easier to support implicit conversions when you don't control both classes (e.g. similar to how extension methods let you add methods to a class you don't control).