diff options
author | Stephane Delcroix <stephane@delcroix.org> | 2017-10-18 09:15:11 +0200 |
---|---|---|
committer | Stephane Delcroix <stephane@delcroix.org> | 2017-10-18 09:17:24 +0200 |
commit | 59d9171a51e5554649720702e4baab603df5601a (patch) | |
tree | fdffded4f6f896fbc364c83f3e623c3121c3545b /Xamarin.Forms.Core | |
parent | 2b55a39cd940bc60095bde966d3475abe6c47d64 (diff) | |
download | xamarin-forms-59d9171a51e5554649720702e4baab603df5601a.tar.gz xamarin-forms-59d9171a51e5554649720702e4baab603df5601a.tar.bz2 xamarin-forms-59d9171a51e5554649720702e4baab603df5601a.zip |
[Xaml] Chain op_implicit for OnPlatform (if needed) (#1176)
* [Xaml] Chain op_implicit for OnPlatform (if needed)
For OnPlatform<T>, if a conversion for T to the destination type exists,
first convert OnPlatform<T> to T, the T to the dest type
Also unify the way we look for op_implicit operators
* [Xaml] only apply the double opImplicit if a flag is set
* [C] allow conversion on parameter
Diffstat (limited to 'Xamarin.Forms.Core')
-rw-r--r-- | Xamarin.Forms.Core/BindableProperty.cs | 12 | ||||
-rw-r--r-- | Xamarin.Forms.Core/Xaml/TypeConversionExtensions.cs | 40 |
2 files changed, 19 insertions, 33 deletions
diff --git a/Xamarin.Forms.Core/BindableProperty.cs b/Xamarin.Forms.Core/BindableProperty.cs index abe47256..40811b09 100644 --- a/Xamarin.Forms.Core/BindableProperty.cs +++ b/Xamarin.Forms.Core/BindableProperty.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; using Xamarin.Forms.Internals; +using Xamarin.Forms.Xaml; namespace Xamarin.Forms { @@ -321,14 +322,9 @@ namespace Xamarin.Forms } else if (!ReturnTypeInfo.IsAssignableFrom(valueType.GetTypeInfo())) { - // Is there an implicit cast operator ? - MethodInfo cast = type.GetRuntimeMethod("op_Implicit", new[] { valueType }); - if (cast != null && cast.ReturnType != type) - cast = null; - if (cast == null) - cast = valueType.GetRuntimeMethod("op_Implicit", new[] { valueType }); - if (cast != null && cast.ReturnType != type) - cast = null; + var cast = type.GetImplicitConversionOperator(fromType: valueType, toType: type) + ?? valueType.GetImplicitConversionOperator(fromType: valueType, toType: type); + if (cast == null) return false; diff --git a/Xamarin.Forms.Core/Xaml/TypeConversionExtensions.cs b/Xamarin.Forms.Core/Xaml/TypeConversionExtensions.cs index 09df9a24..dd0641aa 100644 --- a/Xamarin.Forms.Core/Xaml/TypeConversionExtensions.cs +++ b/Xamarin.Forms.Core/Xaml/TypeConversionExtensions.cs @@ -173,31 +173,9 @@ namespace Xamarin.Forms.Xaml //if there's an implicit conversion, convert if (value != null) { - MethodInfo opImplicit = null; - foreach (var mi in value.GetType().GetRuntimeMethods()) { - if (!mi.IsSpecialName) continue; - if (mi.Name != "op_Implicit") continue; - if (!mi.IsPublic) continue; - if (!toType.IsAssignableFrom(mi.ReturnType)) continue; - var parameters = mi.GetParameters(); - if (parameters.Length != 1) continue; - if (parameters[0].ParameterType != value.GetType()) continue; - opImplicit = mi; - break; - } - if (opImplicit == null) { - foreach (var mi in toType.GetRuntimeMethods()) { - if (!mi.IsSpecialName) continue; - if (mi.Name != "op_Implicit") continue; - if (!mi.IsPublic) continue; - if (!toType.IsAssignableFrom(mi.ReturnType)) continue; - var parameters = mi.GetParameters(); - if (parameters.Length != 1) continue; - if (parameters[0].ParameterType != value.GetType()) continue; - opImplicit = mi; - break; - } - } + var opImplicit = value.GetType().GetImplicitConversionOperator(fromType: value.GetType(), toType: toType) + ?? toType.GetImplicitConversionOperator(fromType: value.GetType(), toType: toType); + if (opImplicit != null) { value = opImplicit.Invoke(null, new[] { value }); return value; @@ -212,5 +190,17 @@ namespace Xamarin.Forms.Xaml return value; } + + internal static MethodInfo GetImplicitConversionOperator(this Type onType, Type fromType, Type toType) + { + var mi = onType.GetRuntimeMethod("op_Implicit", new[] { fromType }); + if (mi == null) return null; + if (!mi.IsSpecialName) return null; + if (!mi.IsPublic) return null; + if (!mi.IsStatic) return null; + if (!toType.IsAssignableFrom(mi.ReturnType)) return null; + + return mi; + } } }
\ No newline at end of file |