如何在UWP项目中包含动态数学评估器?

时间:2016-12-16 10:45:30

标签: c# xamarin uwp xamarin.forms jscript.net

我一直在使用JScript.NET来计算Windows窗体中的表达式(并执行输入代码)。

像这样: (55 % 6) + Math.acos(0.4) - ~ 9 * Math.PI + Math.random() = 33.72725296117653

现在我想在Xamarin Forms上使用相同的东西,但是这个库只适用于Android(尚未测试的iOS),UWP项目一直说不能找到ApplicationException。

不会更新JScript.NET库,因此不推荐使用的Vsa Engine不是问题。

到目前为止尝试了什么

用ILSpy对lbrary进行了解析,但它引用了mscorlib.dll,以至于我放弃了。 I was like... WOW. 寻找Javascript评估者,但他们也引用了mscorlib.dll

我不知道是否应该在项目中包含mscorlib,因为微软似乎不允许这样做。

任何解决方案?提前谢谢。

编辑:

使用JScript 8.0库,如果有帮助的话。

如果可能,建议解决方案与Win8.1 / WinPhone 8.1项目交叉兼容。

2 个答案:

答案 0 :(得分:1)

您可以尝试使用Syncfusion的Xamarin.Forms计算库。

https://www.syncfusion.com/products/xamarin/calculate

它将按照您的预期在所有平台上运行。

答案 1 :(得分:1)

最终我开始使用Jint,这是一个Javascript解释器,免费和开源(不需要担心许可证!)并且在Type上有一些扩展方法它似乎可以使用Win8.1也是如此:

#if WINDOWS_APP || WINDOWS_PHONE_APP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MethodInfos = System.Collections.Generic.IEnumerable<System.Reflection.MethodInfo>;
namespace System.Reflection
{
    public static class CustomExtensions
    {
        public static Assembly Assembly(this Type T) { return T.GetTypeInfo().Assembly; }
        public static MethodInfos GetDeclaredMethods(this Type T) { return T.GetTypeInfo().DeclaredMethods; }
        public static MethodInfo GetDeclaredMethod(this Type T, string name) { return T.GetTypeInfo().GetDeclaredMethod(name); }
        public static bool IsInstanceOfType(this Type T, object o)
        {
            if (o == null)
                return false;

            // No need for transparent proxy casting check here
            // because it never returns true for a non-rutnime type.

            return T.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo());
        }
        public static bool IsAssignableFrom(this Type T1, Type T2)
        { return T1.GetTypeInfo().IsAssignableFrom(T2.GetType().GetTypeInfo()); }
        public static bool IsEnum(this Type type)
        {
            return type.GetTypeInfo().IsEnum;
        }

        public static bool IsGenericType(this Type type)
        {
            return type.GetTypeInfo().IsGenericType;
        }

        public static bool IsValueType(this Type type)
        {
            return type.GetTypeInfo().IsValueType;
        }

        public static bool HasAttribute<T>(this ParameterInfo member) where T : Attribute
        {
            return member.GetCustomAttributes<T>().Any();
        }

        public static Type[] GetGenericArguments(this Type T)
        { return T.GetTypeInfo().GenericTypeArguments; }
        public static MethodInfo GetMethod(this Type T, string Name)
        { return T.GetTypeInfo().GetDeclaredMethod(Name); }
        public static MethodInfo GetMethod(this Type T, string Name, Type[] Types)
        {
            var Params = T.GetTypeInfo().GetDeclaredMethods(Name);
            foreach (var Item in Params)
            {
                bool Yes = false;
                for (int i = 0; i < Types.Count(); i++)
                    Yes |= Types[i] == Item.GetParameters()[i].ParameterType;
                if (Yes) return Item;
            }
            return null;
        }
        public static IEnumerable<Type> GetNestedTypes(this Type T)
        { foreach (TypeInfo Info in T.GetTypeInfo().DeclaredNestedTypes)
                yield return Info.AsType();
        }
        public static IEnumerable<Type> GetNestedTypes(this Type T, BindingFlags Flags)
        {
            foreach (TypeInfo Info in T.GetTypeInfo().DeclaredNestedTypes)
                if(Filter(T.GetTypeInfo(), Flags)) yield return Info.AsType();
        }
        private static bool Filter(TypeInfo Info, BindingFlags Flags)
        {
            bool Return = false;
            if (Flags.HasFlag(BindingFlags.DeclaredOnly)) Return |= Info.IsNested;
            if (Flags.HasFlag(BindingFlags.Instance)) Return |= !(Info.IsAbstract | Info.IsSealed);
            if (Flags.HasFlag(BindingFlags.Static)) Return |= Info.IsAbstract | Info.IsSealed;
            if (Flags.HasFlag(BindingFlags.Public)) Return |= Info.IsPublic;
            if (Flags.HasFlag(BindingFlags.NonPublic)) Return |= Info.IsNotPublic;
            return Return;
        }
        private static bool Filter(MethodInfo Info, BindingFlags Flags)
        {
            bool Return = false;
            if (Flags.HasFlag(BindingFlags.DeclaredOnly)) Return |= Info.IsFamily;
            if (Flags.HasFlag(BindingFlags.Instance)) Return |= !Info.IsStatic;
            if (Flags.HasFlag(BindingFlags.Static)) Return |= Info.IsStatic;
            if (Flags.HasFlag(BindingFlags.Public)) Return |= Info.IsPublic;
            if (Flags.HasFlag(BindingFlags.NonPublic)) Return |= !Info.IsPublic;
            return Return;
        }
        public static IEnumerable<Type> GetTypes(this Assembly A)
        { return A.ExportedTypes; }
    }
    /// <summary>Specifies flags that control binding and the way in which the search for members and types is conducted by reflection.</summary>
    [Flags, Runtime.InteropServices.ComVisible(true)]
    public enum BindingFlags
    {
        /// <summary>Specifies no binding flag.</summary>
        Default = 0,
        /// <summary>Specifies that the case of the member name should not be considered when binding.</summary>
        //IgnoreCase = 1,
        /// <summary>Specifies that only members declared at the level of the supplied type's hierarchy should be considered. Inherited members are not considered.</summary>
        DeclaredOnly = 2,
        /// <summary>Specifies that instance members are to be included in the search.</summary>
        Instance = 4,
        /// <summary>Specifies that static members are to be included in the search.</summary>
        Static = 8,
        /// <summary>Specifies that public members are to be included in the search.</summary>
        Public = 16,
        /// <summary>Specifies that non-public members are to be included in the search.</summary>
        NonPublic = 32,
        /*
        /// <summary>Specifies that public and protected static members up the hierarchy should be returned. Private static members in inherited classes are not returned. Static members include fields, methods, events, and properties. Nested types are not returned.</summary>
        FlattenHierarchy = 64,
        /// <summary>Specifies that a method is to be invoked. This must not be a constructor or a type initializer.</summary>
        InvokeMethod = 256,
        /// <summary>Specifies that Reflection should create an instance of the specified type. Calls the constructor that matches the given arguments. The supplied member name is ignored. If the type of lookup is not specified, (Instance | Public) will apply. It is not possible to call a type initializer.</summary>
        CreateInstance = 512,
        /// <summary>Specifies that the value of the specified field should be returned.</summary>
        GetField = 1024,
        /// <summary>Specifies that the value of the specified field should be set.</summary>
        SetField = 2048,
        /// <summary>Specifies that the value of the specified property should be returned.</summary>
        GetProperty = 4096,
        /// <summary>Specifies that the value of the specified property should be set. For COM properties, specifying this binding flag is equivalent to specifying PutDispProperty and PutRefDispProperty.</summary>
        SetProperty = 8192,
        /// <summary>Specifies that the PROPPUT member on a COM object should be invoked. PROPPUT specifies a property-setting function that uses a value. Use PutDispProperty if a property has both PROPPUT and PROPPUTREF and you need to distinguish which one is called.</summary>
        PutDispProperty = 16384,
        /// <summary>Specifies that the PROPPUTREF member on a COM object should be invoked. PROPPUTREF specifies a property-setting function that uses a reference instead of a value. Use PutRefDispProperty if a property has both PROPPUT and PROPPUTREF and you need to distinguish which one is called.</summary>
        PutRefDispProperty = 32768,
        /// <summary>Specifies that types of the supplied arguments must exactly match the types of the corresponding formal parameters. Reflection throws an exception if the caller supplies a non-null Binder object, since that implies that the caller is supplying BindToXXX implementations that will pick the appropriate method.</summary>
        ExactBinding = 65536,
        /// <summary>Not implemented.</summary>
        SuppressChangeType = 131072,
        /// <summary>Returns the set of members whose parameter count matches the number of supplied arguments. This binding flag is used for methods with parameters that have default values and methods with variable arguments (varargs). This flag should only be used with <see cref="M:System.Type.InvokeMember(System.String,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object,System.Object[],System.Reflection.ParameterModifier[],System.Globalization.CultureInfo,System.String[])" />.</summary>
        OptionalParamBinding = 262144,
        /// <summary>Used in COM interop to specify that the return value of the member can be ignored.</summary>
        IgnoreReturn = 16777216
        */
    }
}
#endif

现在我不必更改我的示例代码并在任何地方顺利评估(甚至Xamarin.iOS,因为Jint不使用DLR或IL发射方法,这又是另一个优势)