在Tibet绑定插件中,类似以下语句:
If(State==1, 'Visible', 'Gone'
由于iOS JIT的限制,并没有对其进行编译,而是进行了求值。
遗憾的是,像==
这样的运算符的求值在不使用动态代码的情况下非常困难...
因此,Tibet ==
运算符尝试将左右两边缩减为三种类型之一:long
、double
或object
- 它通过以下方式实现:
private Type GetLookupTypeFor(object value)
{
if (value == null)
return null;
if (value is long)
return typeof(long);
if (value is double)
return typeof (double);
return typeof (object);
}
从https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding/Combiners/MvxPairwiseValueCombiner.cs#L36获取的内容:
有了这些类型之后,它会调用下面这些方法中的一个,每个方法都使用左侧类型的 ==
运算符或者如果两个类型都是 object
则使用.Equals
:
protected override bool CombineDoubleAndDouble(double input1, double input2, out object value)
{
value = input1 == input2;
return true;
}
protected override bool CombineDoubleAndLong(double input1, long input2, out object value)
{
value = input1 == input2;
return true;
}
这段内容来源于 https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding/Combiners/VeryExperimental/MvxEqualToValueCombiner.cs
对于枚举类型State==1
的情况,我认为左侧将被识别为object
,右侧将被识别为long
- 因此这些值永远不会相等,因为:
protected override bool CombineObjectAndLong(object input1, long input2, out object value)
{
value = false;
return true;
}
在处理当前代码时,我认为让左右两边的值都变成long
或者string
是让测试正常运行的唯一方法。
你可以使用一个值转换器来将枚举类型转换成字符串 - 比如一个ToStringValueConverter
或者一个ToLongValueConverter
。然后你可以像这样使用它:
If(ToLong(State)==1, 'Visible', 'Gone'
或者:
If(ToString(State)=='Running', 'Visible', 'Gone'
显然,展望未来,在Mvx内部也可以改进这个领域 - 无论是在Swiss
和Tibet
之外的任何地方。