[Trimming] Use type converters instead of implicit cast operators (part 1/2) - #21050
Conversation
| ?? toType.GetImplicitConversionOperator(fromType: value.GetType(), toType: toType); | ||
|
|
||
| if (opImplicit != null) | ||
| if (TypeConversionHelper.TryConvert(value, toType, out var convertedValue)) |
There was a problem hiding this comment.
Technically this does change the existing behavior - if there was a TypeConverter, it would not have been used, but now it will be, right?
There was a problem hiding this comment.
Yes, if the existing type converter can convert between the two types, it would be used. But that's the same case as in BindableProperty.TryConvert. If we wanted to make sure that behavior doesn't change, we would have to never use type converters when the MauiImplicitCastOperatorsUsageViaReflectionSupport feature switch is not set.
This behavior would definitely make it even more in line with "don't break any existing app", but maybe it would make adoption of type converters instead of implicit casts slower? This is a good question and I'm not sure which option I prefer.
StephaneDelcroix
left a comment
There was a problem hiding this comment.
if this doesn't affect current behaviour unless NativeAOT is enabled, I'm good
Description of Change
This is a first of two PRs that introduce the possibility to define type conversions using TypeConverters instead of relying on finding and invoking
op_Implicitat runtime via reflection. The main reason for this change is that the way we're working with implicit operators is not trimming-compatible.This PR introduces the internal
TypeConversionHelperthat contains all the updated conversion logic. The second PR will add type converters for all types that have implicit operators in MAUI.Will this break any existing app?
No. This is an opt-in feature. Either the app is trying to run the app with NativeAOT and this feature is necessary for the app to work, or they manually opted into the feature by setting the feature switch to
false(seeFeatureSwitches.md).What if a library or an app doesn't introduce type converters?
When MAUI tries to convert a value and there isn't a suitable type converter, it will try to look up the implicit operator and if it finds it, it will print a runtime warning. This is to give at least some feedback to the customer while making sure the app behaves the same way in Debug mode with Mono and in Release mode with NativeAOT.
I considered throwing an exception instead, but it seems common practice in MAUI to print warnings and fall back to some default value (for example if there's a binding where the path isn't compatible with the given binding context).
What if a library or an app needs to add a type converter for a third-party type?
There's an escape hatch in the form of the app builder extension method to globaly register a type converter for a type. See
FeatureSwitches.md.Why TypeConverter and not IValueConverter?
I chose TypeConverters over IValueConverters because they seem to be better suited for this use case. On the other hand, IValueConverters are easier to write. Feedback is welcome.
Issues Fixed
Fixes #19922
Fixes #5023
Fixes #19397 - we hit 0 trimming warnings in
dotnet new mauion iOS! 🎉/cc @jonathanpeppers @vitek-karas @StephaneDelcroix