using System; using System.Collections.Generic; namespace OpenTap.Addin.Entity { public class NumberData { private readonly static HashSet SupportedTyps = new HashSet { typeof(NumberData), typeof(short), typeof(int), typeof(long), typeof(float), typeof(double), typeof(uint), }; public readonly double value; public static bool Support(object obj) { if (obj is RuntimeVariable rv) { return Support(rv.__data___); } return SupportedTyps.Contains(obj.GetType()); } public static object Format(object obj) { if (Support(obj)) { return new NumberData(obj.ToString()); } return obj; } public NumberData(string value) { this.value = double.Parse(value); } public NumberData(double value) { this.value = value; } public NumberData(NumberData value) { this.value = value.value; } #region NumberData => Number 隐式转换 public static implicit operator short(NumberData nd) { string str = nd.ToString(); if (str.Contains(".")) { throw new ArgumentException($"{nd} can't convert to short."); } return checked((short)nd.value); } public static implicit operator int(NumberData nd) { string str = nd.ToString(); if (str.Contains(".")) { throw new ArgumentException($"{nd} can't convert to int."); } return checked((int)nd.value); } public static implicit operator uint(NumberData nd) { string str = nd.ToString(); if (str.Contains(".")) { throw new ArgumentException($"{nd} can't convert to int."); } return checked((uint)nd.value); } public static implicit operator long(NumberData nd) { string str = nd.ToString(); if (str.Contains(".")) { throw new ArgumentException($"{nd} can't convert to long."); } return checked((long)nd.value); } public static implicit operator float(NumberData nd) { return checked((float)nd.value); } public static implicit operator double(NumberData nd) { return nd.value; } #endregion #region Number => NumberData 显式转换 public static explicit operator NumberData(short obj) { return new NumberData(obj); } public static explicit operator NumberData(int obj) { return new NumberData(obj); } public static explicit operator NumberData(uint obj) { return new NumberData(obj); } public static explicit operator NumberData(long obj) { return new NumberData(obj); } public static explicit operator NumberData(float obj) { return new NumberData(obj); } public static explicit operator NumberData(double obj) { return new NumberData(obj); } #endregion public static NumberData operator +(NumberData operand) => operand; public static NumberData operator -(NumberData operand) => new NumberData(-operand.value); public static NumberData operator +(NumberData left, object right) { var pa = new NumberData(right.ToString()); return new NumberData(left.value + pa.value); } public static NumberData operator -(NumberData left, object right) { var pa = new NumberData(right.ToString()); return new NumberData(left.value - pa.value); } public static NumberData operator *(NumberData left, object right) { var pa = new NumberData(right.ToString()); return new NumberData(left.value * pa.value); } public static NumberData operator /(NumberData left, object right) { var pa = new NumberData(right.ToString()); if (pa.value == 0) { throw new DivideByZeroException(); } return new NumberData(left.value / pa.value); } public static NumberData operator %(NumberData left, object right) { var pa = new NumberData(right.ToString()); if (pa.value == 0) { throw new DivideByZeroException(); } return new NumberData(left.value % pa.value); } public static bool operator >(NumberData left, object right) { var pa = new NumberData(right.ToString()); return left.value > pa.value; } public static bool operator <(NumberData left, object right) { var pa = new NumberData(right.ToString()); return left.value < pa.value; } public static bool operator >=(NumberData left, object right) { var pa = new NumberData(right.ToString()); return left.value >= pa.value; } public static bool operator <=(NumberData left, object right) { var pa = new NumberData(right.ToString()); return left.value <= pa.value; } public static bool operator ==(NumberData left, object right) { var pa = new NumberData(right.ToString()); return left.value == pa.value; } public static bool operator !=(NumberData left, object right) { var pa = new NumberData(right.ToString()); return left.value != pa.value; } public static NumberData operator +(object left, NumberData right) { var pa = new NumberData(left.ToString()); return new NumberData(pa.value + right.value); } public static NumberData operator -(object left, NumberData right) { var pa = new NumberData(left.ToString()); return new NumberData(pa.value - right.value); } public static NumberData operator *(object left, NumberData right) { var pa = new NumberData(left.ToString()); return new NumberData(pa.value * right.value); } public static NumberData operator /(object left, NumberData right) { if (right.value == 0) { throw new DivideByZeroException(); } var pa = new NumberData(left.ToString()); return new NumberData(pa.value / right.value); } public static NumberData operator %(object left, NumberData right) { if (right.value == 0) { throw new DivideByZeroException(); } var pa = new NumberData(left.ToString()); return new NumberData(pa.value % right.value); } public static bool operator >(object left, NumberData right) { var pa = new NumberData(left.ToString()); return pa.value > right.value; } public static bool operator <(object left, NumberData right) { var pa = new NumberData(left.ToString()); return pa.value < right.value; } public static bool operator >=(object left, NumberData right) { var pa = new NumberData(left.ToString()); return pa.value >= right.value; } public static bool operator <=(object left, NumberData right) { var pa = new NumberData(left.ToString()); return pa.value <= right.value; } public static bool operator ==(object left, NumberData right) { var pa = new NumberData(left.ToString()); return pa.value == right.value; } public static bool operator ==(NumberData left, NumberData right) { return left.value == right.value; } public static bool operator !=(NumberData left, NumberData right) { return left.value != right.value; } public static bool operator >(NumberData left, NumberData right) { return left.value > right.value; } public static bool operator >=(NumberData left, NumberData right) { return left.value >= right.value; } public static bool operator <(NumberData left, NumberData right) { return left.value < right.value; } public static bool operator <=(NumberData left, NumberData right) { return left.value <= right.value; } public static bool operator !=(object left, NumberData right) { var pa = new NumberData(left.ToString()); return pa.value != right.value; } public override bool Equals(object obj) { if (obj is NumberData nd) { return this.value.Equals(nd.value); } return value.Equals(new NumberData(obj.ToString()).value); } public override int GetHashCode() { return value.GetHashCode(); } public override string ToString() { return value.ToString(); } } }