summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Core
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2017-10-18 09:15:11 +0200
committerStephane Delcroix <stephane@delcroix.org>2017-10-18 09:17:24 +0200
commit59d9171a51e5554649720702e4baab603df5601a (patch)
treefdffded4f6f896fbc364c83f3e623c3121c3545b /Xamarin.Forms.Core
parent2b55a39cd940bc60095bde966d3475abe6c47d64 (diff)
downloadxamarin-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.cs12
-rw-r--r--Xamarin.Forms.Core/Xaml/TypeConversionExtensions.cs40
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