using System; using System.Reflection; using System.Runtime.InteropServices; namespace Serein.Flow.SerinExpression { public abstract class ConditionResolver { public abstract bool Evaluate(object obj); } public class PassConditionResolver : ConditionResolver { public Operator Op { get; set; } public override bool Evaluate(object obj) { return Op switch { Operator.Pass => true, Operator.NotPass => false, _ => throw new NotSupportedException("不支持的条件类型") }; } public enum Operator { Pass, NotPass, } } public class ValueTypeConditionResolver : ConditionResolver where T : struct, IComparable { public enum Operator { /// /// 不进行任何操作 /// Node, /// /// 大于 /// GreaterThan, /// /// 小于 /// LessThan, /// /// 等于 /// Equal, /// /// 大于或等于 /// GreaterThanOrEqual, /// /// 小于或等于 /// LessThanOrEqual, /// /// 在两者之间 /// InRange, /// /// 不在两者之间 /// OutOfRange } public Operator Op { get; set; } public T Value { get; set; } public T RangeStart { get; set; } public T RangeEnd { get; set; } public string ArithmeticExpression { get; set; } public override bool Evaluate(object obj) { if (obj is T typedObj) { double numericValue = Convert.ToDouble(typedObj); if (!string.IsNullOrEmpty(ArithmeticExpression)) { numericValue = SerinArithmeticExpressionEvaluator.Evaluate(ArithmeticExpression, numericValue); } T evaluatedValue = (T)Convert.ChangeType(numericValue, typeof(T)); return Op switch { Operator.GreaterThan => evaluatedValue.CompareTo(Value) > 0, Operator.LessThan => evaluatedValue.CompareTo(Value) < 0, Operator.Equal => evaluatedValue.CompareTo(Value) == 0, Operator.GreaterThanOrEqual => evaluatedValue.CompareTo(Value) >= 0, Operator.LessThanOrEqual => evaluatedValue.CompareTo(Value) <= 0, Operator.InRange => evaluatedValue.CompareTo(RangeStart) >= 0 && evaluatedValue.CompareTo(RangeEnd) <= 0, Operator.OutOfRange => evaluatedValue.CompareTo(RangeStart) < 0 || evaluatedValue.CompareTo(RangeEnd) > 0, _ => throw new NotSupportedException("不支持的条件类型") }; /* switch (Op) { case Operator.GreaterThan: return evaluatedValue.CompareTo(Value) > 0; case Operator.LessThan: return evaluatedValue.CompareTo(Value) < 0; case Operator.Equal: return evaluatedValue.CompareTo(Value) == 0; case Operator.GreaterThanOrEqual: return evaluatedValue.CompareTo(Value) >= 0; case Operator.LessThanOrEqual: return evaluatedValue.CompareTo(Value) <= 0; case Operator.InRange: return evaluatedValue.CompareTo(RangeStart) >= 0 && evaluatedValue.CompareTo(RangeEnd) <= 0; case Operator.OutOfRange: return evaluatedValue.CompareTo(RangeStart) < 0 || evaluatedValue.CompareTo(RangeEnd) > 0; }*/ } return false; } } public class BoolConditionResolver : ConditionResolver { public enum Operator { /// /// 是 /// Is } public Operator Op { get; set; } public bool Value { get; set; } public override bool Evaluate(object obj) { if (obj is bool boolObj) { return boolObj == Value; /*switch (Op) { case Operator.Is: return boolObj == Value; }*/ } return false; } } public class StringConditionResolver : ConditionResolver { public enum Operator { /// /// 出现过 /// Contains, /// /// 没有出现过 /// DoesNotContain, /// /// 相等 /// Equal, /// /// 不相等 /// NotEqual, /// /// 起始字符串等于 /// StartsWith, /// /// 结束字符串等于 /// EndsWith } public Operator Op { get; set; } public string Value { get; set; } public override bool Evaluate(object obj) { if (obj is string strObj) { return Op switch { Operator.Contains => strObj.Contains(Value), Operator.DoesNotContain => !strObj.Contains(Value), Operator.Equal => strObj == Value, Operator.NotEqual => strObj != Value, Operator.StartsWith => strObj.StartsWith(Value), Operator.EndsWith => strObj.EndsWith(Value), _ => throw new NotSupportedException("不支持的条件类型"), }; /* switch (Op) { case Operator.Contains: return strObj.Contains(Value); case Operator.DoesNotContain: return !strObj.Contains(Value); case Operator.Equal: return strObj == Value; case Operator.NotEqual: return strObj != Value; case Operator.StartsWith: return strObj.StartsWith(Value); case Operator.EndsWith: return strObj.EndsWith(Value); }*/ } return false; } } public class MemberConditionResolver : ConditionResolver where T : struct, IComparable { //public string MemberPath { get; set; } public ValueTypeConditionResolver.Operator Op { get; set; } public object? TargetObj { get; set; } public T Value { get; set; } public string ArithmeticExpression { get; set; } public override bool Evaluate(object? obj) { //object? memberValue = GetMemberValue(obj, MemberPath); if (TargetObj is T typedObj) { return new ValueTypeConditionResolver { Op = Op, Value = Value, ArithmeticExpression = ArithmeticExpression, }.Evaluate(typedObj); } return false; } //private object? GetMemberValue(object? obj, string memberPath) //{ // string[] members = memberPath[1..].Split('.'); // foreach (var member in members) // { // if (obj == null) return null; // Type type = obj.GetType(); // PropertyInfo? propertyInfo = type.GetProperty(member); // FieldInfo? fieldInfo = type.GetField(member); // if (propertyInfo != null) // obj = propertyInfo.GetValue(obj); // else if (fieldInfo != null) // obj = fieldInfo.GetValue(obj); // else // throw new ArgumentException($"Member {member} not found in type {type.FullName}"); // } // return obj; //} } public class MemberStringConditionResolver : ConditionResolver { public string MemberPath { get; set; } public StringConditionResolver.Operator Op { get; set; } public string Value { get; set; } public override bool Evaluate(object obj) { object memberValue = GetMemberValue(obj, MemberPath); if (memberValue is string strObj) { return new StringConditionResolver { Op = Op, Value = Value }.Evaluate(strObj); } return false; } private object GetMemberValue(object? obj, string memberPath) { string[] members = memberPath[1..].Split('.'); foreach (var member in members) { if (obj == null) return null; Type type = obj.GetType(); PropertyInfo? propertyInfo = type.GetProperty(member); FieldInfo? fieldInfo = type.GetField(member); if (propertyInfo != null) obj = propertyInfo.GetValue(obj); else if (fieldInfo != null) obj = fieldInfo.GetValue(obj); else throw new ArgumentException($"Member {member} not found in type {type.FullName}"); } return obj; } private static string GetArithmeticExpression(string part) { int startIndex = part.IndexOf('['); int endIndex = part.IndexOf(']'); if (startIndex >= 0 && endIndex > startIndex) { return part.Substring(startIndex + 1, endIndex - startIndex - 1); } return null; } } }